diff --git a/.gitignore b/.gitignore
index 2e2c85df1..a66bf9cff 100644
--- a/.gitignore
+++ b/.gitignore
@@ -66,7 +66,7 @@ coverage.all
 /integrations/mssql.ini
 /node_modules
 /modules/indexer/issues/indexers
-
+routers/repo/authorized_keys
 
 # Snapcraft
 snap/.snapcraft/
diff --git a/docs/content/doc/advanced/migrations.en-us.md b/docs/content/doc/advanced/migrations.en-us.md
new file mode 100644
index 000000000..7db9cad81
--- /dev/null
+++ b/docs/content/doc/advanced/migrations.en-us.md
@@ -0,0 +1,72 @@
+---
+date: "2019-04-15T17:29:00+08:00"
+title: "Advanced: Migrations Interfaces"
+slug: "migrations-interfaces"
+weight: 30
+toc: true
+draft: false
+menu:
+  sidebar:
+    parent: "advanced"
+    name: "Migrations Interfaces"
+    weight: 55
+    identifier: "migrations-interfaces"
+---
+
+# Migration Features
+
+The new migration features were introduced in Gitea 1.9.0. It defines two interfaces to support migrating 
+repositories data from other git host platforms to gitea or, in the future migrating gitea data to other 
+git host platforms. Currently, only the migrations from github via APIv3 to Gitea is implemented.
+
+First of all, Gitea defines some standard objects in packages `modules/migrations/base`. They are
+ `Repository`, `Milestone`, `Release`, `Label`, `Issue`, `Comment`, `PullRequest`.
+
+## Downloader Interfaces
+
+To migrate from a new git host platform, there are two steps to be updated.
+
+- You should implement a `Downloader` which will get all kinds of repository informations.
+- You should implement a `DownloaderFactory` which is used to detect if the URL matches and 
+create a Downloader.
+- You'll need to register the `DownloaderFactory` via `RegisterDownloaderFactory` on init.
+
+```Go
+type Downloader interface {
+	GetRepoInfo() (*Repository, error)
+	GetMilestones() ([]*Milestone, error)
+	GetReleases() ([]*Release, error)
+	GetLabels() ([]*Label, error)
+	GetIssues(start, limit int) ([]*Issue, error)
+	GetComments(issueNumber int64) ([]*Comment, error)
+	GetPullRequests(start, limit int) ([]*PullRequest, error)
+}
+```
+
+```Go
+type DownloaderFactory interface {
+	Match(opts MigrateOptions) (bool, error)
+	New(opts MigrateOptions) (Downloader, error)
+}
+```
+
+## Uploader Interface
+
+Currently, only a `GiteaLocalUploader` is implemented, so we only save downloaded 
+data via this `Uploader` on the local Gitea instance. Other uploaders are not supported
+and will be implemented in future.
+
+```Go
+// Uploader uploads all the informations
+type Uploader interface {
+	CreateRepo(repo *Repository, includeWiki bool) error
+	CreateMilestone(milestone *Milestone) error
+	CreateRelease(release *Release) error
+	CreateLabel(label *Label) error
+	CreateIssue(issue *Issue) error
+	CreateComment(issueNumber int64, comment *Comment) error
+	CreatePullRequest(pr *PullRequest) error
+	Rollback() error
+}
+
+```
\ No newline at end of file
diff --git a/go.mod b/go.mod
index 38edd5c15..f7e7a683a 100644
--- a/go.mod
+++ b/go.mod
@@ -62,6 +62,7 @@ require (
 	github.com/gogits/chardet v0.0.0-20150115103509-2404f7772561
 	github.com/gogits/cron v0.0.0-20160810035002-7f3990acf183
 	github.com/gogo/protobuf v1.2.1 // indirect
+	github.com/google/go-github/v24 v24.0.1
 	github.com/gorilla/context v1.1.1
 	github.com/issue9/assert v1.3.2 // indirect
 	github.com/issue9/identicon v0.0.0-20160320065130-d36b54562f4c
@@ -115,7 +116,7 @@ require (
 	go.etcd.io/bbolt v1.3.2 // indirect
 	golang.org/x/crypto v0.0.0-20180904163835-0709b304e793
 	golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519
-	golang.org/x/oauth2 v0.0.0-20181101160152-c453e0c75759 // indirect
+	golang.org/x/oauth2 v0.0.0-20181101160152-c453e0c75759
 	golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223
 	golang.org/x/text v0.3.0
 	gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
diff --git a/go.sum b/go.sum
index 3b7061f84..ca64a7a5e 100644
--- a/go.sum
+++ b/go.sum
@@ -142,6 +142,12 @@ github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pO
 github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
+github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
+github.com/google/go-github/v24 v24.0.1 h1:KCt1LjMJEey1qvPXxa9SjaWxwTsCWSq6p2Ju57UR4Q4=
+github.com/google/go-github/v24 v24.0.1/go.mod h1:CRqaW1Uns1TCkP0wqTpxYyRxRjxwvKU/XSS44u6X74M=
+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/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
@@ -309,17 +315,21 @@ github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
 github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
 go.etcd.io/bbolt v1.3.2 h1:Z/90sZLPOeCy2PwprqkFa25PdkusRzaj9P8zm/KNyvk=
 go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I=
 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519 h1:x6rhz8Y9CjbgQkccRGmELH6K+LJj7tOoh3XWeC1yaQM=
 golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/oauth2 v0.0.0-20180620175406-ef147856a6dd/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20181101160152-c453e0c75759 h1:TMrx+Qdx7uJAeUbv15N72h5Hmyb5+VDjEiMufAEAM04=
 golang.org/x/oauth2 v0.0.0-20181101160152-c453e0c75759/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180824143301-4910a1d54f87/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
@@ -327,6 +337,7 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5h
 golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.2.0 h1:S0iUepdCWODXRvtE+gcRDd15L+k+k1AiHlMiMjefH24=
 google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
diff --git a/models/migrate.go b/models/migrate.go
new file mode 100644
index 000000000..54f9a3e24
--- /dev/null
+++ b/models/migrate.go
@@ -0,0 +1,145 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package models
+
+import "github.com/go-xorm/xorm"
+
+// InsertIssue insert one issue to database
+func InsertIssue(issue *Issue, labelIDs []int64) error {
+	sess := x.NewSession()
+	if err := sess.Begin(); err != nil {
+		return err
+	}
+
+	if err := insertIssue(sess, issue, labelIDs); err != nil {
+		return err
+	}
+	return sess.Commit()
+}
+
+func insertIssue(sess *xorm.Session, issue *Issue, labelIDs []int64) error {
+	if issue.MilestoneID > 0 {
+		sess.Incr("num_issues")
+		if issue.IsClosed {
+			sess.Incr("num_closed_issues")
+		}
+		if _, err := sess.ID(issue.MilestoneID).NoAutoTime().Update(new(Milestone)); err != nil {
+			return err
+		}
+	}
+	if _, err := sess.NoAutoTime().Insert(issue); err != nil {
+		return err
+	}
+	var issueLabels = make([]IssueLabel, 0, len(labelIDs))
+	for _, labelID := range labelIDs {
+		issueLabels = append(issueLabels, IssueLabel{
+			IssueID: issue.ID,
+			LabelID: labelID,
+		})
+	}
+	if _, err := sess.Insert(issueLabels); err != nil {
+		return err
+	}
+	if !issue.IsPull {
+		sess.ID(issue.RepoID).Incr("num_issues")
+		if issue.IsClosed {
+			sess.Incr("num_closed_issues")
+		}
+	} else {
+		sess.ID(issue.RepoID).Incr("num_pulls")
+		if issue.IsClosed {
+			sess.Incr("num_closed_pulls")
+		}
+	}
+	if _, err := sess.NoAutoTime().Update(issue.Repo); err != nil {
+		return err
+	}
+
+	sess.Incr("num_issues")
+	if issue.IsClosed {
+		sess.Incr("num_closed_issues")
+	}
+	if _, err := sess.In("id", labelIDs).Update(new(Label)); err != nil {
+		return err
+	}
+
+	if issue.MilestoneID > 0 {
+		if _, err := sess.ID(issue.MilestoneID).SetExpr("completeness", "num_closed_issues * 100 / num_issues").Update(new(Milestone)); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+// InsertComment inserted a comment
+func InsertComment(comment *Comment) error {
+	sess := x.NewSession()
+	defer sess.Close()
+	if err := sess.Begin(); err != nil {
+		return err
+	}
+	if _, err := sess.NoAutoTime().Insert(comment); err != nil {
+		return err
+	}
+	if _, err := sess.ID(comment.IssueID).Incr("num_comments").Update(new(Issue)); err != nil {
+		return err
+	}
+	return sess.Commit()
+}
+
+// InsertPullRequest inserted a pull request
+func InsertPullRequest(pr *PullRequest, labelIDs []int64) error {
+	sess := x.NewSession()
+	defer sess.Close()
+	if err := sess.Begin(); err != nil {
+		return err
+	}
+	if err := insertIssue(sess, pr.Issue, labelIDs); err != nil {
+		return err
+	}
+	pr.IssueID = pr.Issue.ID
+	if _, err := sess.NoAutoTime().Insert(pr); err != nil {
+		return err
+	}
+	return sess.Commit()
+}
+
+// MigrateRelease migrates release
+func MigrateRelease(rel *Release) error {
+	sess := x.NewSession()
+	if err := sess.Begin(); err != nil {
+		return err
+	}
+
+	var oriRel = Release{
+		RepoID:  rel.RepoID,
+		TagName: rel.TagName,
+	}
+	exist, err := sess.Get(&oriRel)
+	if err != nil {
+		return err
+	}
+	if !exist {
+		if _, err := sess.NoAutoTime().Insert(rel); err != nil {
+			return err
+		}
+	} else {
+		rel.ID = oriRel.ID
+		if _, err := sess.ID(rel.ID).Cols("target, title, note, is_tag, num_commits").Update(rel); err != nil {
+			return err
+		}
+	}
+
+	for i := 0; i < len(rel.Attachments); i++ {
+		rel.Attachments[i].ReleaseID = rel.ID
+	}
+
+	if _, err := sess.NoAutoTime().Insert(rel.Attachments); err != nil {
+		return err
+	}
+
+	return sess.Commit()
+}
diff --git a/models/release_test.go b/models/release_test.go
index 39c661305..f3f61240e 100644
--- a/models/release_test.go
+++ b/models/release_test.go
@@ -107,6 +107,7 @@ func TestRelease_MirrorDelete(t *testing.T) {
 		IsPrivate:   false,
 		IsMirror:    true,
 		RemoteAddr:  repoPath,
+		Wiki:        true,
 	}
 	mirror, err := MigrateRepository(user, user, migrationOptions)
 	assert.NoError(t, err)
diff --git a/models/repo.go b/models/repo.go
index 936ad2ae3..e8af9aa2d 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -896,6 +896,7 @@ type MigrateRepoOptions struct {
 	IsPrivate   bool
 	IsMirror    bool
 	RemoteAddr  string
+	Wiki        bool // include wiki repository
 }
 
 /*
@@ -917,7 +918,7 @@ func wikiRemoteURL(remote string) string {
 	return ""
 }
 
-// MigrateRepository migrates a existing repository from other project hosting.
+// MigrateRepository migrates an existing repository from other project hosting.
 func MigrateRepository(doer, u *User, opts MigrateRepoOptions) (*Repository, error) {
 	repo, err := CreateRepository(doer, u, CreateRepoOptions{
 		Name:        opts.Name,
@@ -930,7 +931,6 @@ func MigrateRepository(doer, u *User, opts MigrateRepoOptions) (*Repository, err
 	}
 
 	repoPath := RepoPath(u.Name, opts.Name)
-	wikiPath := WikiPath(u.Name, opts.Name)
 
 	if u.IsOrganization() {
 		t, err := u.GetOwnerTeam()
@@ -956,22 +956,25 @@ func MigrateRepository(doer, u *User, opts MigrateRepoOptions) (*Repository, err
 		return repo, fmt.Errorf("Clone: %v", err)
 	}
 
-	wikiRemotePath := wikiRemoteURL(opts.RemoteAddr)
-	if len(wikiRemotePath) > 0 {
-		if err := os.RemoveAll(wikiPath); err != nil {
-			return repo, fmt.Errorf("Failed to remove %s: %v", wikiPath, err)
-		}
-
-		if err = git.Clone(wikiRemotePath, wikiPath, git.CloneRepoOptions{
-			Mirror:  true,
-			Quiet:   true,
-			Timeout: migrateTimeout,
-			Branch:  "master",
-		}); err != nil {
-			log.Warn("Clone wiki: %v", err)
+	if opts.Wiki {
+		wikiPath := WikiPath(u.Name, opts.Name)
+		wikiRemotePath := wikiRemoteURL(opts.RemoteAddr)
+		if len(wikiRemotePath) > 0 {
 			if err := os.RemoveAll(wikiPath); err != nil {
 				return repo, fmt.Errorf("Failed to remove %s: %v", wikiPath, err)
 			}
+
+			if err = git.Clone(wikiRemotePath, wikiPath, git.CloneRepoOptions{
+				Mirror:  true,
+				Quiet:   true,
+				Timeout: migrateTimeout,
+				Branch:  "master",
+			}); err != nil {
+				log.Warn("Clone wiki: %v", err)
+				if err := os.RemoveAll(wikiPath); err != nil {
+					return repo, fmt.Errorf("Failed to remove %s: %v", wikiPath, err)
+				}
+			}
 		}
 	}
 
diff --git a/modules/auth/repo_form.go b/modules/auth/repo_form.go
index f48f2f5e6..0333c3c92 100644
--- a/modules/auth/repo_form.go
+++ b/modules/auth/repo_form.go
@@ -51,10 +51,16 @@ type MigrateRepoForm struct {
 	// required: true
 	UID int64 `json:"uid" binding:"Required"`
 	// required: true
-	RepoName    string `json:"repo_name" binding:"Required;AlphaDashDot;MaxSize(100)"`
-	Mirror      bool   `json:"mirror"`
-	Private     bool   `json:"private"`
-	Description string `json:"description" binding:"MaxSize(255)"`
+	RepoName     string `json:"repo_name" binding:"Required;AlphaDashDot;MaxSize(100)"`
+	Mirror       bool   `json:"mirror"`
+	Private      bool   `json:"private"`
+	Description  string `json:"description" binding:"MaxSize(255)"`
+	Wiki         bool   `json:"wiki"`
+	Milestones   bool   `json:"milestones"`
+	Labels       bool   `json:"labels"`
+	Issues       bool   `json:"issues"`
+	PullRequests bool   `json:"pull_requests"`
+	Releases     bool   `json:"releases"`
 }
 
 // Validate validates the fields
diff --git a/modules/migrations/base/comment.go b/modules/migrations/base/comment.go
new file mode 100644
index 000000000..0ff0963f0
--- /dev/null
+++ b/modules/migrations/base/comment.go
@@ -0,0 +1,17 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Copyright 2018 Jonas Franz. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package base
+
+import "time"
+
+// Comment is a standard comment information
+type Comment struct {
+	PosterName  string
+	PosterEmail string
+	Created     time.Time
+	Content     string
+	Reactions   *Reactions
+}
diff --git a/modules/migrations/base/downloader.go b/modules/migrations/base/downloader.go
new file mode 100644
index 000000000..9a09fdac0
--- /dev/null
+++ b/modules/migrations/base/downloader.go
@@ -0,0 +1,23 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Copyright 2018 Jonas Franz. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package base
+
+// Downloader downloads the site repo informations
+type Downloader interface {
+	GetRepoInfo() (*Repository, error)
+	GetMilestones() ([]*Milestone, error)
+	GetReleases() ([]*Release, error)
+	GetLabels() ([]*Label, error)
+	GetIssues(start, limit int) ([]*Issue, error)
+	GetComments(issueNumber int64) ([]*Comment, error)
+	GetPullRequests(start, limit int) ([]*PullRequest, error)
+}
+
+// DownloaderFactory defines an interface to match a downloader implementation and create a downloader
+type DownloaderFactory interface {
+	Match(opts MigrateOptions) (bool, error)
+	New(opts MigrateOptions) (Downloader, error)
+}
diff --git a/modules/migrations/base/issue.go b/modules/migrations/base/issue.go
new file mode 100644
index 000000000..ddadd0c2b
--- /dev/null
+++ b/modules/migrations/base/issue.go
@@ -0,0 +1,24 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Copyright 2018 Jonas Franz. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package base
+
+import "time"
+
+// Issue is a standard issue information
+type Issue struct {
+	Number      int64
+	PosterName  string
+	PosterEmail string
+	Title       string
+	Content     string
+	Milestone   string
+	State       string // closed, open
+	IsLocked    bool
+	Created     time.Time
+	Closed      *time.Time
+	Labels      []*Label
+	Reactions   *Reactions
+}
diff --git a/modules/migrations/base/label.go b/modules/migrations/base/label.go
new file mode 100644
index 000000000..0c86b547f
--- /dev/null
+++ b/modules/migrations/base/label.go
@@ -0,0 +1,13 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Copyright 2018 Jonas Franz. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package base
+
+// Label defines a standard label informations
+type Label struct {
+	Name        string
+	Color       string
+	Description string
+}
diff --git a/modules/migrations/base/milestone.go b/modules/migrations/base/milestone.go
new file mode 100644
index 000000000..8736aa6cf
--- /dev/null
+++ b/modules/migrations/base/milestone.go
@@ -0,0 +1,19 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Copyright 2018 Jonas Franz. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package base
+
+import "time"
+
+// Milestone defines a standard milestone
+type Milestone struct {
+	Title       string
+	Description string
+	Deadline    *time.Time
+	Created     time.Time
+	Updated     *time.Time
+	Closed      *time.Time
+	State       string
+}
diff --git a/modules/migrations/base/options.go b/modules/migrations/base/options.go
new file mode 100644
index 000000000..262981b93
--- /dev/null
+++ b/modules/migrations/base/options.go
@@ -0,0 +1,26 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Copyright 2018 Jonas Franz. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package base
+
+// MigrateOptions defines the way a repository gets migrated
+type MigrateOptions struct {
+	RemoteURL    string
+	AuthUsername string
+	AuthPassword string
+	Name         string
+	Description  string
+
+	Wiki              bool
+	Issues            bool
+	Milestones        bool
+	Labels            bool
+	Releases          bool
+	Comments          bool
+	PullRequests      bool
+	Private           bool
+	Mirror            bool
+	IgnoreIssueAuthor bool // if true will not add original author information before issues or comments content.
+}
diff --git a/modules/migrations/base/pullrequest.go b/modules/migrations/base/pullrequest.go
new file mode 100644
index 000000000..515cab3f9
--- /dev/null
+++ b/modules/migrations/base/pullrequest.go
@@ -0,0 +1,53 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Copyright 2018 Jonas Franz. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package base
+
+import (
+	"fmt"
+	"time"
+)
+
+// PullRequest defines a standard pull request information
+type PullRequest struct {
+	Number         int64
+	Title          string
+	PosterName     string
+	PosterEmail    string
+	Content        string
+	Milestone      string
+	State          string
+	Created        time.Time
+	Closed         *time.Time
+	Labels         []*Label
+	PatchURL       string
+	Merged         bool
+	MergedTime     *time.Time
+	MergeCommitSHA string
+	Head           PullRequestBranch
+	Base           PullRequestBranch
+	Assignee       string
+	Assignees      []string
+	IsLocked       bool
+}
+
+// IsForkPullRequest returns true if the pull request from a forked repository but not the same repository
+func (p *PullRequest) IsForkPullRequest() bool {
+	return p.Head.RepoPath() != p.Base.RepoPath()
+}
+
+// PullRequestBranch represents a pull request branch
+type PullRequestBranch struct {
+	CloneURL  string
+	Ref       string
+	SHA       string
+	RepoName  string
+	OwnerName string
+}
+
+// RepoPath returns pull request repo path
+func (p PullRequestBranch) RepoPath() string {
+	return fmt.Sprintf("%s/%s", p.OwnerName, p.RepoName)
+}
diff --git a/modules/migrations/base/reaction.go b/modules/migrations/base/reaction.go
new file mode 100644
index 000000000..fd7a9543d
--- /dev/null
+++ b/modules/migrations/base/reaction.go
@@ -0,0 +1,17 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Copyright 2018 Jonas Franz. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package base
+
+// Reactions represents a summary of reactions.
+type Reactions struct {
+	TotalCount int
+	PlusOne    int
+	MinusOne   int
+	Laugh      int
+	Confused   int
+	Heart      int
+	Hooray     int
+}
diff --git a/modules/migrations/base/release.go b/modules/migrations/base/release.go
new file mode 100644
index 000000000..4ebc37315
--- /dev/null
+++ b/modules/migrations/base/release.go
@@ -0,0 +1,31 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package base
+
+import "time"
+
+// ReleaseAsset represents a release asset
+type ReleaseAsset struct {
+	URL           string
+	Name          string
+	ContentType   *string
+	Size          *int
+	DownloadCount *int
+	Created       time.Time
+	Updated       time.Time
+}
+
+// Release represents a release
+type Release struct {
+	TagName         string
+	TargetCommitish string
+	Name            string
+	Body            string
+	Draft           bool
+	Prerelease      bool
+	Assets          []ReleaseAsset
+	Created         time.Time
+	Published       time.Time
+}
diff --git a/modules/migrations/base/repo.go b/modules/migrations/base/repo.go
new file mode 100644
index 000000000..907d8fc09
--- /dev/null
+++ b/modules/migrations/base/repo.go
@@ -0,0 +1,18 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Copyright 2018 Jonas Franz. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package base
+
+// Repository defines a standard repository information
+type Repository struct {
+	Name         string
+	Owner        string
+	IsPrivate    bool
+	IsMirror     bool
+	Description  string
+	AuthUsername string
+	AuthPassword string
+	CloneURL     string
+}
diff --git a/modules/migrations/base/uploader.go b/modules/migrations/base/uploader.go
new file mode 100644
index 000000000..eaeb10314
--- /dev/null
+++ b/modules/migrations/base/uploader.go
@@ -0,0 +1,18 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Copyright 2018 Jonas Franz. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package base
+
+// Uploader uploads all the informations
+type Uploader interface {
+	CreateRepo(repo *Repository, includeWiki bool) error
+	CreateMilestone(milestone *Milestone) error
+	CreateRelease(release *Release) error
+	CreateLabel(label *Label) error
+	CreateIssue(issue *Issue) error
+	CreateComment(issueNumber int64, comment *Comment) error
+	CreatePullRequest(pr *PullRequest) error
+	Rollback() error
+}
diff --git a/modules/migrations/error.go b/modules/migrations/error.go
new file mode 100644
index 000000000..a48484d15
--- /dev/null
+++ b/modules/migrations/error.go
@@ -0,0 +1,29 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Copyright 2018 Jonas Franz. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package migrations
+
+import (
+	"errors"
+
+	"github.com/google/go-github/v24/github"
+)
+
+var (
+	// ErrNotSupported returns the error not supported
+	ErrNotSupported = errors.New("not supported")
+)
+
+// IsRateLimitError returns true if the err is github.RateLimitError
+func IsRateLimitError(err error) bool {
+	_, ok := err.(*github.RateLimitError)
+	return ok
+}
+
+// IsTwoFactorAuthError returns true if the err is github.TwoFactorAuthError
+func IsTwoFactorAuthError(err error) bool {
+	_, ok := err.(*github.TwoFactorAuthError)
+	return ok
+}
diff --git a/modules/migrations/git.go b/modules/migrations/git.go
new file mode 100644
index 000000000..cbaa37282
--- /dev/null
+++ b/modules/migrations/git.go
@@ -0,0 +1,69 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package migrations
+
+import (
+	"code.gitea.io/gitea/modules/migrations/base"
+)
+
+var (
+	_ base.Downloader = &PlainGitDownloader{}
+)
+
+// PlainGitDownloader implements a Downloader interface to clone git from a http/https URL
+type PlainGitDownloader struct {
+	ownerName string
+	repoName  string
+	remoteURL string
+}
+
+// NewPlainGitDownloader creates a git Downloader
+func NewPlainGitDownloader(ownerName, repoName, remoteURL string) *PlainGitDownloader {
+	return &PlainGitDownloader{
+		ownerName: ownerName,
+		repoName:  repoName,
+		remoteURL: remoteURL,
+	}
+}
+
+// GetRepoInfo returns a repository information
+func (g *PlainGitDownloader) GetRepoInfo() (*base.Repository, error) {
+	// convert github repo to stand Repo
+	return &base.Repository{
+		Owner:    g.ownerName,
+		Name:     g.repoName,
+		CloneURL: g.remoteURL,
+	}, nil
+}
+
+// GetMilestones returns milestones
+func (g *PlainGitDownloader) GetMilestones() ([]*base.Milestone, error) {
+	return nil, ErrNotSupported
+}
+
+// GetLabels returns labels
+func (g *PlainGitDownloader) GetLabels() ([]*base.Label, error) {
+	return nil, ErrNotSupported
+}
+
+// GetReleases returns releases
+func (g *PlainGitDownloader) GetReleases() ([]*base.Release, error) {
+	return nil, ErrNotSupported
+}
+
+// GetIssues returns issues according start and limit
+func (g *PlainGitDownloader) GetIssues(start, limit int) ([]*base.Issue, error) {
+	return nil, ErrNotSupported
+}
+
+// GetComments returns comments according issueNumber
+func (g *PlainGitDownloader) GetComments(issueNumber int64) ([]*base.Comment, error) {
+	return nil, ErrNotSupported
+}
+
+// GetPullRequests returns pull requests according start and limit
+func (g *PlainGitDownloader) GetPullRequests(start, limit int) ([]*base.PullRequest, error) {
+	return nil, ErrNotSupported
+}
diff --git a/modules/migrations/gitea.go b/modules/migrations/gitea.go
new file mode 100644
index 000000000..dcffb360e
--- /dev/null
+++ b/modules/migrations/gitea.go
@@ -0,0 +1,403 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Copyright 2018 Jonas Franz. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package migrations
+
+import (
+	"fmt"
+	"io"
+	"net/http"
+	"os"
+	"path"
+	"path/filepath"
+	"strings"
+	"sync"
+	"time"
+
+	"code.gitea.io/gitea/models"
+	"code.gitea.io/gitea/modules/git"
+	"code.gitea.io/gitea/modules/log"
+	"code.gitea.io/gitea/modules/migrations/base"
+	"code.gitea.io/gitea/modules/setting"
+	"code.gitea.io/gitea/modules/util"
+
+	gouuid "github.com/satori/go.uuid"
+)
+
+var (
+	_ base.Uploader = &GiteaLocalUploader{}
+)
+
+// GiteaLocalUploader implements an Uploader to gitea sites
+type GiteaLocalUploader struct {
+	doer        *models.User
+	repoOwner   string
+	repoName    string
+	repo        *models.Repository
+	labels      sync.Map
+	milestones  sync.Map
+	issues      sync.Map
+	gitRepo     *git.Repository
+	prHeadCache map[string]struct{}
+}
+
+// NewGiteaLocalUploader creates an gitea Uploader via gitea API v1
+func NewGiteaLocalUploader(doer *models.User, repoOwner, repoName string) *GiteaLocalUploader {
+	return &GiteaLocalUploader{
+		doer:        doer,
+		repoOwner:   repoOwner,
+		repoName:    repoName,
+		prHeadCache: make(map[string]struct{}),
+	}
+}
+
+// CreateRepo creates a repository
+func (g *GiteaLocalUploader) CreateRepo(repo *base.Repository, includeWiki bool) error {
+	owner, err := models.GetUserByName(g.repoOwner)
+	if err != nil {
+		return err
+	}
+
+	r, err := models.MigrateRepository(g.doer, owner, models.MigrateRepoOptions{
+		Name:        g.repoName,
+		Description: repo.Description,
+		IsMirror:    repo.IsMirror,
+		RemoteAddr:  repo.CloneURL,
+		IsPrivate:   repo.IsPrivate,
+		Wiki:        includeWiki,
+	})
+	if err != nil {
+		return err
+	}
+	g.repo = r
+	g.gitRepo, err = git.OpenRepository(r.RepoPath())
+	return err
+}
+
+// CreateMilestone creates milestone
+func (g *GiteaLocalUploader) CreateMilestone(milestone *base.Milestone) error {
+	var deadline util.TimeStamp
+	if milestone.Deadline != nil {
+		deadline = util.TimeStamp(milestone.Deadline.Unix())
+	}
+	if deadline == 0 {
+		deadline = util.TimeStamp(time.Date(9999, 1, 1, 0, 0, 0, 0, setting.UILocation).Unix())
+	}
+	var ms = models.Milestone{
+		RepoID:       g.repo.ID,
+		Name:         milestone.Title,
+		Content:      milestone.Description,
+		IsClosed:     milestone.State == "close",
+		DeadlineUnix: deadline,
+	}
+	if ms.IsClosed && milestone.Closed != nil {
+		ms.ClosedDateUnix = util.TimeStamp(milestone.Closed.Unix())
+	}
+	err := models.NewMilestone(&ms)
+
+	if err != nil {
+		return err
+	}
+	g.milestones.Store(ms.Name, ms.ID)
+	return nil
+}
+
+// CreateLabel creates label
+func (g *GiteaLocalUploader) CreateLabel(label *base.Label) error {
+	var lb = models.Label{
+		RepoID:      g.repo.ID,
+		Name:        label.Name,
+		Description: label.Description,
+		Color:       fmt.Sprintf("#%s", label.Color),
+	}
+	err := models.NewLabel(&lb)
+	if err != nil {
+		return err
+	}
+	g.labels.Store(lb.Name, lb.ID)
+	return nil
+}
+
+// CreateRelease creates release
+func (g *GiteaLocalUploader) CreateRelease(release *base.Release) error {
+	var rel = models.Release{
+		RepoID:       g.repo.ID,
+		PublisherID:  g.doer.ID,
+		TagName:      release.TagName,
+		LowerTagName: strings.ToLower(release.TagName),
+		Target:       release.TargetCommitish,
+		Title:        release.Name,
+		Sha1:         release.TargetCommitish,
+		Note:         release.Body,
+		IsDraft:      release.Draft,
+		IsPrerelease: release.Prerelease,
+		IsTag:        false,
+		CreatedUnix:  util.TimeStamp(release.Created.Unix()),
+	}
+
+	// calc NumCommits
+	commit, err := g.gitRepo.GetCommit(rel.TagName)
+	if err != nil {
+		return fmt.Errorf("GetCommit: %v", err)
+	}
+	rel.NumCommits, err = commit.CommitsCount()
+	if err != nil {
+		return fmt.Errorf("CommitsCount: %v", err)
+	}
+
+	for _, asset := range release.Assets {
+		var attach = models.Attachment{
+			UUID:          gouuid.NewV4().String(),
+			Name:          asset.Name,
+			DownloadCount: int64(*asset.DownloadCount),
+			Size:          int64(*asset.Size),
+			CreatedUnix:   util.TimeStamp(asset.Created.Unix()),
+		}
+
+		// download attachment
+		resp, err := http.Get(asset.URL)
+		if err != nil {
+			return err
+		}
+		defer resp.Body.Close()
+
+		localPath := attach.LocalPath()
+		if err = os.MkdirAll(path.Dir(localPath), os.ModePerm); err != nil {
+			return fmt.Errorf("MkdirAll: %v", err)
+		}
+
+		fw, err := os.Create(localPath)
+		if err != nil {
+			return fmt.Errorf("Create: %v", err)
+		}
+		defer fw.Close()
+
+		if _, err := io.Copy(fw, resp.Body); err != nil {
+			return err
+		}
+
+		rel.Attachments = append(rel.Attachments, &attach)
+	}
+
+	return models.MigrateRelease(&rel)
+}
+
+// CreateIssue creates issue
+func (g *GiteaLocalUploader) CreateIssue(issue *base.Issue) error {
+	var labelIDs []int64
+	for _, label := range issue.Labels {
+		id, ok := g.labels.Load(label.Name)
+		if !ok {
+			return fmt.Errorf("Label %s missing when create issue", label.Name)
+		}
+		labelIDs = append(labelIDs, id.(int64))
+	}
+
+	var milestoneID int64
+	if issue.Milestone != "" {
+		milestone, ok := g.milestones.Load(issue.Milestone)
+		if !ok {
+			return fmt.Errorf("Milestone %s missing when create issue", issue.Milestone)
+		}
+		milestoneID = milestone.(int64)
+	}
+
+	var is = models.Issue{
+		RepoID:      g.repo.ID,
+		Repo:        g.repo,
+		Index:       issue.Number,
+		PosterID:    g.doer.ID,
+		Title:       issue.Title,
+		Content:     issue.Content,
+		IsClosed:    issue.State == "closed",
+		IsLocked:    issue.IsLocked,
+		MilestoneID: milestoneID,
+		CreatedUnix: util.TimeStamp(issue.Created.Unix()),
+	}
+	if issue.Closed != nil {
+		is.ClosedUnix = util.TimeStamp(issue.Closed.Unix())
+	}
+
+	err := models.InsertIssue(&is, labelIDs)
+	if err != nil {
+		return err
+	}
+	g.issues.Store(issue.Number, is.ID)
+	// TODO: add reactions
+	return err
+}
+
+// CreateComment creates comment
+func (g *GiteaLocalUploader) CreateComment(issueNumber int64, comment *base.Comment) error {
+	var issueID int64
+	if issueIDStr, ok := g.issues.Load(issueNumber); !ok {
+		issue, err := models.GetIssueByIndex(g.repo.ID, issueNumber)
+		if err != nil {
+			return err
+		}
+		issueID = issue.ID
+		g.issues.Store(issueNumber, issueID)
+	} else {
+		issueID = issueIDStr.(int64)
+	}
+
+	var cm = models.Comment{
+		IssueID:     issueID,
+		Type:        models.CommentTypeComment,
+		PosterID:    g.doer.ID,
+		Content:     comment.Content,
+		CreatedUnix: util.TimeStamp(comment.Created.Unix()),
+	}
+	err := models.InsertComment(&cm)
+	// TODO: Reactions
+	return err
+}
+
+// CreatePullRequest creates pull request
+func (g *GiteaLocalUploader) CreatePullRequest(pr *base.PullRequest) error {
+	var labelIDs []int64
+	for _, label := range pr.Labels {
+		id, ok := g.labels.Load(label.Name)
+		if !ok {
+			return fmt.Errorf("Label %s missing when create issue", label.Name)
+		}
+		labelIDs = append(labelIDs, id.(int64))
+	}
+
+	var milestoneID int64
+	if pr.Milestone != "" {
+		milestone, ok := g.milestones.Load(pr.Milestone)
+		if !ok {
+			return fmt.Errorf("Milestone %s missing when create issue", pr.Milestone)
+		}
+		milestoneID = milestone.(int64)
+	}
+
+	// download patch file
+	resp, err := http.Get(pr.PatchURL)
+	if err != nil {
+		return err
+	}
+	defer resp.Body.Close()
+	pullDir := filepath.Join(g.repo.RepoPath(), "pulls")
+	if err = os.MkdirAll(pullDir, os.ModePerm); err != nil {
+		return err
+	}
+	f, err := os.Create(filepath.Join(pullDir, fmt.Sprintf("%d.patch", pr.Number)))
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+	_, err = io.Copy(f, resp.Body)
+	if err != nil {
+		return err
+	}
+
+	// set head information
+	pullHead := filepath.Join(g.repo.RepoPath(), "refs", "pull", fmt.Sprintf("%d", pr.Number))
+	if err := os.MkdirAll(pullHead, os.ModePerm); err != nil {
+		return err
+	}
+	p, err := os.Create(filepath.Join(pullHead, "head"))
+	if err != nil {
+		return err
+	}
+	defer p.Close()
+	_, err = p.WriteString(pr.Head.SHA)
+	if err != nil {
+		return err
+	}
+
+	var head = "unknown repository"
+	if pr.IsForkPullRequest() {
+		if pr.Head.OwnerName != "" {
+			remote := pr.Head.OwnerName
+			_, ok := g.prHeadCache[remote]
+			if !ok {
+				// git remote add
+				err := g.gitRepo.AddRemote(remote, pr.Head.CloneURL, true)
+				if err != nil {
+					log.Error("AddRemote failed: %s", err)
+				} else {
+					g.prHeadCache[remote] = struct{}{}
+					ok = true
+				}
+			}
+
+			if ok {
+				_, err = git.NewCommand("fetch", remote, pr.Head.Ref).RunInDir(g.repo.RepoPath())
+				if err != nil {
+					log.Error("Fetch branch from %s failed: %v", pr.Head.CloneURL, err)
+				} else {
+					headBranch := filepath.Join(g.repo.RepoPath(), "refs", "heads", pr.Head.OwnerName, pr.Head.Ref)
+					if err := os.MkdirAll(filepath.Dir(headBranch), os.ModePerm); err != nil {
+						return err
+					}
+					b, err := os.Create(headBranch)
+					if err != nil {
+						return err
+					}
+					defer b.Close()
+					_, err = b.WriteString(pr.Head.SHA)
+					if err != nil {
+						return err
+					}
+					head = pr.Head.OwnerName + "/" + pr.Head.Ref
+				}
+			}
+		}
+	} else {
+		head = pr.Head.Ref
+	}
+
+	var pullRequest = models.PullRequest{
+		HeadRepoID:   g.repo.ID,
+		HeadBranch:   head,
+		HeadUserName: g.repoOwner,
+		BaseRepoID:   g.repo.ID,
+		BaseBranch:   pr.Base.Ref,
+		MergeBase:    pr.Base.SHA,
+		Index:        pr.Number,
+		HasMerged:    pr.Merged,
+
+		Issue: &models.Issue{
+			RepoID:      g.repo.ID,
+			Repo:        g.repo,
+			Title:       pr.Title,
+			Index:       pr.Number,
+			PosterID:    g.doer.ID,
+			Content:     pr.Content,
+			MilestoneID: milestoneID,
+			IsPull:      true,
+			IsClosed:    pr.State == "closed",
+			IsLocked:    pr.IsLocked,
+			CreatedUnix: util.TimeStamp(pr.Created.Unix()),
+		},
+	}
+
+	if pullRequest.Issue.IsClosed && pr.Closed != nil {
+		pullRequest.Issue.ClosedUnix = util.TimeStamp(pr.Closed.Unix())
+	}
+	if pullRequest.HasMerged && pr.MergedTime != nil {
+		pullRequest.MergedUnix = util.TimeStamp(pr.MergedTime.Unix())
+		pullRequest.MergedCommitID = pr.MergeCommitSHA
+		pullRequest.MergerID = g.doer.ID
+	}
+
+	// TODO: reactions
+	// TODO: assignees
+
+	return models.InsertPullRequest(&pullRequest, labelIDs)
+}
+
+// Rollback when migrating failed, this will rollback all the changes.
+func (g *GiteaLocalUploader) Rollback() error {
+	if g.repo != nil && g.repo.ID > 0 {
+		if err := models.DeleteRepository(g.doer, g.repo.OwnerID, g.repo.ID); err != nil {
+			return err
+		}
+	}
+	return nil
+}
diff --git a/modules/migrations/gitea_test.go b/modules/migrations/gitea_test.go
new file mode 100644
index 000000000..22da7da17
--- /dev/null
+++ b/modules/migrations/gitea_test.go
@@ -0,0 +1,95 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Copyright 2018 Jonas Franz. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package migrations
+
+import (
+	"testing"
+	"time"
+
+	"code.gitea.io/gitea/models"
+	"code.gitea.io/gitea/modules/util"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestGiteaUploadRepo(t *testing.T) {
+	// FIXME: Since no accesskey or user/password will trigger rate limit of github, just skip
+	t.Skip()
+
+	models.PrepareTestEnv(t)
+
+	user := models.AssertExistsAndLoadBean(t, &models.User{ID: 1}).(*models.User)
+
+	var (
+		downloader = NewGithubDownloaderV3("", "", "go-xorm", "builder")
+		repoName   = "builder-" + time.Now().Format("2006-01-02-15-04-05")
+		uploader   = NewGiteaLocalUploader(user, user.Name, repoName)
+	)
+
+	err := migrateRepository(downloader, uploader, MigrateOptions{
+		RemoteURL:    "https://github.com/go-xorm/builder",
+		Name:         repoName,
+		AuthUsername: "",
+
+		Wiki:              true,
+		Issues:            true,
+		Milestones:        true,
+		Labels:            true,
+		Releases:          true,
+		Comments:          true,
+		PullRequests:      true,
+		Private:           true,
+		Mirror:            false,
+		IgnoreIssueAuthor: false,
+	})
+	assert.NoError(t, err)
+
+	repo := models.AssertExistsAndLoadBean(t, &models.Repository{OwnerID: user.ID, Name: repoName}).(*models.Repository)
+	assert.True(t, repo.HasWiki())
+
+	milestones, err := models.GetMilestones(repo.ID, 0, false, "")
+	assert.NoError(t, err)
+	assert.EqualValues(t, 1, len(milestones))
+
+	milestones, err = models.GetMilestones(repo.ID, 0, true, "")
+	assert.NoError(t, err)
+	assert.EqualValues(t, 0, len(milestones))
+
+	labels, err := models.GetLabelsByRepoID(repo.ID, "")
+	assert.NoError(t, err)
+	assert.EqualValues(t, 11, len(labels))
+
+	releases, err := models.GetReleasesByRepoID(repo.ID, models.FindReleasesOptions{
+		IncludeTags: true,
+	}, 0, 10)
+	assert.NoError(t, err)
+	assert.EqualValues(t, 8, len(releases))
+
+	releases, err = models.GetReleasesByRepoID(repo.ID, models.FindReleasesOptions{
+		IncludeTags: false,
+	}, 0, 10)
+	assert.NoError(t, err)
+	assert.EqualValues(t, 1, len(releases))
+
+	issues, err := models.Issues(&models.IssuesOptions{
+		RepoIDs:  []int64{repo.ID},
+		IsPull:   util.OptionalBoolFalse,
+		SortType: "oldest",
+	})
+	assert.NoError(t, err)
+	assert.EqualValues(t, 14, len(issues))
+	assert.NoError(t, issues[0].LoadDiscussComments())
+	assert.EqualValues(t, 0, len(issues[0].Comments))
+
+	pulls, _, err := models.PullRequests(repo.ID, &models.PullRequestsOptions{
+		SortType: "oldest",
+	})
+	assert.NoError(t, err)
+	assert.EqualValues(t, 34, len(pulls))
+	assert.NoError(t, pulls[0].LoadIssue())
+	assert.NoError(t, pulls[0].Issue.LoadDiscussComments())
+	assert.EqualValues(t, 2, len(pulls[0].Issue.Comments))
+}
diff --git a/modules/migrations/github.go b/modules/migrations/github.go
new file mode 100644
index 000000000..8e1cd67df
--- /dev/null
+++ b/modules/migrations/github.go
@@ -0,0 +1,475 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Copyright 2018 Jonas Franz. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package migrations
+
+import (
+	"context"
+	"fmt"
+	"net/http"
+	"net/url"
+	"strings"
+
+	"code.gitea.io/gitea/modules/log"
+	"code.gitea.io/gitea/modules/migrations/base"
+
+	"github.com/google/go-github/v24/github"
+	"golang.org/x/oauth2"
+)
+
+var (
+	_ base.Downloader        = &GithubDownloaderV3{}
+	_ base.DownloaderFactory = &GithubDownloaderV3Factory{}
+)
+
+func init() {
+	RegisterDownloaderFactory(&GithubDownloaderV3Factory{})
+}
+
+// GithubDownloaderV3Factory defines a github downloader v3 factory
+type GithubDownloaderV3Factory struct {
+}
+
+// Match returns ture if the migration remote URL matched this downloader factory
+func (f *GithubDownloaderV3Factory) Match(opts base.MigrateOptions) (bool, error) {
+	u, err := url.Parse(opts.RemoteURL)
+	if err != nil {
+		return false, err
+	}
+
+	return u.Host == "github.com" && opts.AuthUsername != "", nil
+}
+
+// New returns a Downloader related to this factory according MigrateOptions
+func (f *GithubDownloaderV3Factory) New(opts base.MigrateOptions) (base.Downloader, error) {
+	u, err := url.Parse(opts.RemoteURL)
+	if err != nil {
+		return nil, err
+	}
+
+	fields := strings.Split(u.Path, "/")
+	oldOwner := fields[1]
+	oldName := strings.TrimSuffix(fields[2], ".git")
+
+	log.Trace("Create github downloader: %s/%s", oldOwner, oldName)
+
+	return NewGithubDownloaderV3(opts.AuthUsername, opts.AuthPassword, oldOwner, oldName), nil
+}
+
+// GithubDownloaderV3 implements a Downloader interface to get repository informations
+// from github via APIv3
+type GithubDownloaderV3 struct {
+	ctx       context.Context
+	client    *github.Client
+	repoOwner string
+	repoName  string
+	userName  string
+	password  string
+}
+
+// NewGithubDownloaderV3 creates a github Downloader via github v3 API
+func NewGithubDownloaderV3(userName, password, repoOwner, repoName string) *GithubDownloaderV3 {
+	var downloader = GithubDownloaderV3{
+		userName:  userName,
+		password:  password,
+		ctx:       context.Background(),
+		repoOwner: repoOwner,
+		repoName:  repoName,
+	}
+
+	var client *http.Client
+	if userName != "" {
+		if password == "" {
+			ts := oauth2.StaticTokenSource(
+				&oauth2.Token{AccessToken: userName},
+			)
+			client = oauth2.NewClient(downloader.ctx, ts)
+		} else {
+			client = &http.Client{
+				Transport: &http.Transport{
+					Proxy: func(req *http.Request) (*url.URL, error) {
+						req.SetBasicAuth(userName, password)
+						return nil, nil
+					},
+				},
+			}
+		}
+	}
+	downloader.client = github.NewClient(client)
+	return &downloader
+}
+
+// GetRepoInfo returns a repository information
+func (g *GithubDownloaderV3) GetRepoInfo() (*base.Repository, error) {
+	gr, _, err := g.client.Repositories.Get(g.ctx, g.repoOwner, g.repoName)
+	if err != nil {
+		return nil, err
+	}
+
+	// convert github repo to stand Repo
+	return &base.Repository{
+		Owner:       g.repoOwner,
+		Name:        gr.GetName(),
+		IsPrivate:   *gr.Private,
+		Description: gr.GetDescription(),
+		CloneURL:    gr.GetCloneURL(),
+	}, nil
+}
+
+// GetMilestones returns milestones
+func (g *GithubDownloaderV3) GetMilestones() ([]*base.Milestone, error) {
+	var perPage = 100
+	var milestones = make([]*base.Milestone, 0, perPage)
+	for i := 1; ; i++ {
+		ms, _, err := g.client.Issues.ListMilestones(g.ctx, g.repoOwner, g.repoName,
+			&github.MilestoneListOptions{
+				State: "all",
+				ListOptions: github.ListOptions{
+					Page:    i,
+					PerPage: perPage,
+				}})
+		if err != nil {
+			return nil, err
+		}
+
+		for _, m := range ms {
+			var desc string
+			if m.Description != nil {
+				desc = *m.Description
+			}
+			var state = "open"
+			if m.State != nil {
+				state = *m.State
+			}
+			milestones = append(milestones, &base.Milestone{
+				Title:       *m.Title,
+				Description: desc,
+				Deadline:    m.DueOn,
+				State:       state,
+				Created:     *m.CreatedAt,
+				Updated:     m.UpdatedAt,
+				Closed:      m.ClosedAt,
+			})
+		}
+		if len(ms) < perPage {
+			break
+		}
+	}
+	return milestones, nil
+}
+
+func convertGithubLabel(label *github.Label) *base.Label {
+	var desc string
+	if label.Description != nil {
+		desc = *label.Description
+	}
+	return &base.Label{
+		Name:        *label.Name,
+		Color:       *label.Color,
+		Description: desc,
+	}
+}
+
+// GetLabels returns labels
+func (g *GithubDownloaderV3) GetLabels() ([]*base.Label, error) {
+	var perPage = 100
+	var labels = make([]*base.Label, 0, perPage)
+	for i := 1; ; i++ {
+		ls, _, err := g.client.Issues.ListLabels(g.ctx, g.repoOwner, g.repoName,
+			&github.ListOptions{
+				Page:    i,
+				PerPage: perPage,
+			})
+		if err != nil {
+			return nil, err
+		}
+
+		for _, label := range ls {
+			labels = append(labels, convertGithubLabel(label))
+		}
+		if len(ls) < perPage {
+			break
+		}
+	}
+	return labels, nil
+}
+
+func (g *GithubDownloaderV3) convertGithubRelease(rel *github.RepositoryRelease) *base.Release {
+	var (
+		name string
+		desc string
+	)
+	if rel.Body != nil {
+		desc = *rel.Body
+	}
+	if rel.Name != nil {
+		name = *rel.Name
+	}
+
+	r := &base.Release{
+		TagName:         *rel.TagName,
+		TargetCommitish: *rel.TargetCommitish,
+		Name:            name,
+		Body:            desc,
+		Draft:           *rel.Draft,
+		Prerelease:      *rel.Prerelease,
+		Created:         rel.CreatedAt.Time,
+		Published:       rel.PublishedAt.Time,
+	}
+
+	for _, asset := range rel.Assets {
+		u, _ := url.Parse(*asset.BrowserDownloadURL)
+		u.User = url.UserPassword(g.userName, g.password)
+		r.Assets = append(r.Assets, base.ReleaseAsset{
+			URL:           u.String(),
+			Name:          *asset.Name,
+			ContentType:   asset.ContentType,
+			Size:          asset.Size,
+			DownloadCount: asset.DownloadCount,
+			Created:       asset.CreatedAt.Time,
+			Updated:       asset.UpdatedAt.Time,
+		})
+	}
+	return r
+}
+
+// GetReleases returns releases
+func (g *GithubDownloaderV3) GetReleases() ([]*base.Release, error) {
+	var perPage = 100
+	var releases = make([]*base.Release, 0, perPage)
+	for i := 1; ; i++ {
+		ls, _, err := g.client.Repositories.ListReleases(g.ctx, g.repoOwner, g.repoName,
+			&github.ListOptions{
+				Page:    i,
+				PerPage: perPage,
+			})
+		if err != nil {
+			return nil, err
+		}
+
+		for _, release := range ls {
+			releases = append(releases, g.convertGithubRelease(release))
+		}
+		if len(ls) < perPage {
+			break
+		}
+	}
+	return releases, nil
+}
+
+func convertGithubReactions(reactions *github.Reactions) *base.Reactions {
+	return &base.Reactions{
+		TotalCount: *reactions.TotalCount,
+		PlusOne:    *reactions.PlusOne,
+		MinusOne:   *reactions.MinusOne,
+		Laugh:      *reactions.Laugh,
+		Confused:   *reactions.Confused,
+		Heart:      *reactions.Heart,
+		Hooray:     *reactions.Hooray,
+	}
+}
+
+// GetIssues returns issues according start and limit
+func (g *GithubDownloaderV3) GetIssues(start, limit int) ([]*base.Issue, error) {
+	var perPage = 100
+	opt := &github.IssueListByRepoOptions{
+		Sort:      "created",
+		Direction: "asc",
+		State:     "all",
+		ListOptions: github.ListOptions{
+			PerPage: perPage,
+		},
+	}
+	var allIssues = make([]*base.Issue, 0, limit)
+	for {
+		issues, resp, err := g.client.Issues.ListByRepo(g.ctx, g.repoOwner, g.repoName, opt)
+		if err != nil {
+			return nil, fmt.Errorf("error while listing repos: %v", err)
+		}
+		for _, issue := range issues {
+			if issue.IsPullRequest() {
+				continue
+			}
+			var body string
+			if issue.Body != nil {
+				body = *issue.Body
+			}
+			var milestone string
+			if issue.Milestone != nil {
+				milestone = *issue.Milestone.Title
+			}
+			var labels = make([]*base.Label, 0, len(issue.Labels))
+			for _, l := range issue.Labels {
+				labels = append(labels, convertGithubLabel(&l))
+			}
+			var reactions *base.Reactions
+			if issue.Reactions != nil {
+				reactions = convertGithubReactions(issue.Reactions)
+			}
+
+			var email string
+			if issue.User.Email != nil {
+				email = *issue.User.Email
+			}
+			allIssues = append(allIssues, &base.Issue{
+				Title:       *issue.Title,
+				Number:      int64(*issue.Number),
+				PosterName:  *issue.User.Login,
+				PosterEmail: email,
+				Content:     body,
+				Milestone:   milestone,
+				State:       *issue.State,
+				Created:     *issue.CreatedAt,
+				Labels:      labels,
+				Reactions:   reactions,
+				Closed:      issue.ClosedAt,
+				IsLocked:    *issue.Locked,
+			})
+			if len(allIssues) >= limit {
+				return allIssues, nil
+			}
+		}
+		if resp.NextPage == 0 {
+			break
+		}
+		opt.Page = resp.NextPage
+	}
+	return allIssues, nil
+}
+
+// GetComments returns comments according issueNumber
+func (g *GithubDownloaderV3) GetComments(issueNumber int64) ([]*base.Comment, error) {
+	var allComments = make([]*base.Comment, 0, 100)
+	opt := &github.IssueListCommentsOptions{
+		Sort:      "created",
+		Direction: "asc",
+		ListOptions: github.ListOptions{
+			PerPage: 100,
+		},
+	}
+	for {
+		comments, resp, err := g.client.Issues.ListComments(g.ctx, g.repoOwner, g.repoName, int(issueNumber), opt)
+		if err != nil {
+			return nil, fmt.Errorf("error while listing repos: %v", err)
+		}
+		for _, comment := range comments {
+			var email string
+			if comment.User.Email != nil {
+				email = *comment.User.Email
+			}
+			var reactions *base.Reactions
+			if comment.Reactions != nil {
+				reactions = convertGithubReactions(comment.Reactions)
+			}
+			allComments = append(allComments, &base.Comment{
+				PosterName:  *comment.User.Login,
+				PosterEmail: email,
+				Content:     *comment.Body,
+				Created:     *comment.CreatedAt,
+				Reactions:   reactions,
+			})
+		}
+		if resp.NextPage == 0 {
+			break
+		}
+		opt.Page = resp.NextPage
+	}
+	return allComments, nil
+}
+
+// GetPullRequests returns pull requests according start and limit
+func (g *GithubDownloaderV3) GetPullRequests(start, limit int) ([]*base.PullRequest, error) {
+	opt := &github.PullRequestListOptions{
+		Sort:      "created",
+		Direction: "asc",
+		State:     "all",
+		ListOptions: github.ListOptions{
+			PerPage: 100,
+		},
+	}
+	var allPRs = make([]*base.PullRequest, 0, 100)
+	for {
+		prs, resp, err := g.client.PullRequests.List(g.ctx, g.repoOwner, g.repoName, opt)
+		if err != nil {
+			return nil, fmt.Errorf("error while listing repos: %v", err)
+		}
+		for _, pr := range prs {
+			var body string
+			if pr.Body != nil {
+				body = *pr.Body
+			}
+			var milestone string
+			if pr.Milestone != nil {
+				milestone = *pr.Milestone.Title
+			}
+			var labels = make([]*base.Label, 0, len(pr.Labels))
+			for _, l := range pr.Labels {
+				labels = append(labels, convertGithubLabel(l))
+			}
+
+			// FIXME: This API missing reactions, we may need another extra request to get reactions
+
+			var email string
+			if pr.User.Email != nil {
+				email = *pr.User.Email
+			}
+			var merged bool
+			// pr.Merged is not valid, so use MergedAt to test if it's merged
+			if pr.MergedAt != nil {
+				merged = true
+			}
+
+			var headRepoName string
+			var cloneURL string
+			if pr.Head.Repo != nil {
+				headRepoName = *pr.Head.Repo.Name
+				cloneURL = *pr.Head.Repo.CloneURL
+			}
+			var mergeCommitSHA string
+			if pr.MergeCommitSHA != nil {
+				mergeCommitSHA = *pr.MergeCommitSHA
+			}
+
+			allPRs = append(allPRs, &base.PullRequest{
+				Title:          *pr.Title,
+				Number:         int64(*pr.Number),
+				PosterName:     *pr.User.Login,
+				PosterEmail:    email,
+				Content:        body,
+				Milestone:      milestone,
+				State:          *pr.State,
+				Created:        *pr.CreatedAt,
+				Closed:         pr.ClosedAt,
+				Labels:         labels,
+				Merged:         merged,
+				MergeCommitSHA: mergeCommitSHA,
+				MergedTime:     pr.MergedAt,
+				IsLocked:       pr.ActiveLockReason != nil,
+				Head: base.PullRequestBranch{
+					Ref:       *pr.Head.Ref,
+					SHA:       *pr.Head.SHA,
+					RepoName:  headRepoName,
+					OwnerName: *pr.Head.User.Login,
+					CloneURL:  cloneURL,
+				},
+				Base: base.PullRequestBranch{
+					Ref:       *pr.Base.Ref,
+					SHA:       *pr.Base.SHA,
+					RepoName:  *pr.Base.Repo.Name,
+					OwnerName: *pr.Base.User.Login,
+				},
+				PatchURL: *pr.PatchURL,
+			})
+			if len(allPRs) >= limit {
+				return allPRs, nil
+			}
+		}
+		if resp.NextPage == 0 {
+			break
+		}
+		opt.Page = resp.NextPage
+	}
+	return allPRs, nil
+}
diff --git a/modules/migrations/github_test.go b/modules/migrations/github_test.go
new file mode 100644
index 000000000..e1d3efad5
--- /dev/null
+++ b/modules/migrations/github_test.go
@@ -0,0 +1,448 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Copyright 2018 Jonas Franz. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package migrations
+
+import (
+	"testing"
+	"time"
+
+	"code.gitea.io/gitea/modules/migrations/base"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func assertMilestoneEqual(t *testing.T, title, dueOn, created, updated, closed, state string, ms *base.Milestone) {
+	var tmPtr *time.Time
+	if dueOn != "" {
+		tm, err := time.Parse("2006-01-02 15:04:05 -0700 MST", dueOn)
+		assert.NoError(t, err)
+		tmPtr = &tm
+	}
+	var (
+		createdTM time.Time
+		updatedTM *time.Time
+		closedTM  *time.Time
+	)
+	if created != "" {
+		var err error
+		createdTM, err = time.Parse("2006-01-02 15:04:05 -0700 MST", created)
+		assert.NoError(t, err)
+	}
+	if updated != "" {
+		updatedTemp, err := time.Parse("2006-01-02 15:04:05 -0700 MST", updated)
+		assert.NoError(t, err)
+		updatedTM = &updatedTemp
+	}
+	if closed != "" {
+		closedTemp, err := time.Parse("2006-01-02 15:04:05 -0700 MST", closed)
+		assert.NoError(t, err)
+		closedTM = &closedTemp
+	}
+
+	assert.EqualValues(t, &base.Milestone{
+		Title:    title,
+		Deadline: tmPtr,
+		State:    state,
+		Created:  createdTM,
+		Updated:  updatedTM,
+		Closed:   closedTM,
+	}, ms)
+}
+
+func assertLabelEqual(t *testing.T, name, color string, label *base.Label) {
+	assert.EqualValues(t, &base.Label{
+		Name:  name,
+		Color: color,
+	}, label)
+}
+
+func TestGitHubDownloadRepo(t *testing.T) {
+	downloader := NewGithubDownloaderV3("", "", "go-gitea", "gitea")
+	repo, err := downloader.GetRepoInfo()
+	assert.NoError(t, err)
+	assert.EqualValues(t, &base.Repository{
+		Name:        "gitea",
+		Owner:       "go-gitea",
+		Description: "Git with a cup of tea, painless self-hosted git service",
+		CloneURL:    "https://github.com/go-gitea/gitea.git",
+	}, repo)
+
+	milestones, err := downloader.GetMilestones()
+	assert.NoError(t, err)
+	// before this tool release, we have 39 milestones on github.com/go-gitea/gitea
+	assert.True(t, len(milestones) >= 39)
+
+	for _, milestone := range milestones {
+		switch milestone.Title {
+		case "1.0.0":
+			assertMilestoneEqual(t, "1.0.0", "2016-12-23 08:00:00 +0000 UTC",
+				"2016-11-02 18:06:55 +0000 UTC",
+				"2016-12-29 10:26:00 +0000 UTC",
+				"2016-12-24 00:40:56 +0000 UTC",
+				"closed", milestone)
+		case "1.1.0":
+			assertMilestoneEqual(t, "1.1.0", "2017-02-24 08:00:00 +0000 UTC",
+				"2016-11-03 08:40:10 +0000 UTC",
+				"2017-06-15 05:04:36 +0000 UTC",
+				"2017-03-09 21:22:21 +0000 UTC",
+				"closed", milestone)
+		case "1.2.0":
+			assertMilestoneEqual(t, "1.2.0", "2017-04-24 07:00:00 +0000 UTC",
+				"2016-11-03 08:40:15 +0000 UTC",
+				"2017-12-10 02:43:29 +0000 UTC",
+				"2017-10-12 08:24:28 +0000 UTC",
+				"closed", milestone)
+		case "1.3.0":
+			assertMilestoneEqual(t, "1.3.0", "2017-11-29 08:00:00 +0000 UTC",
+				"2017-03-03 08:08:59 +0000 UTC",
+				"2017-12-04 07:48:44 +0000 UTC",
+				"2017-11-29 18:39:00 +0000 UTC",
+				"closed", milestone)
+		case "1.4.0":
+			assertMilestoneEqual(t, "1.4.0", "2018-01-25 08:00:00 +0000 UTC",
+				"2017-08-23 11:02:37 +0000 UTC",
+				"2018-03-25 20:01:56 +0000 UTC",
+				"2018-03-25 20:01:56 +0000 UTC",
+				"closed", milestone)
+		case "1.5.0":
+			assertMilestoneEqual(t, "1.5.0", "2018-06-15 07:00:00 +0000 UTC",
+				"2017-12-30 04:21:56 +0000 UTC",
+				"2018-09-05 16:34:22 +0000 UTC",
+				"2018-08-11 08:45:01 +0000 UTC",
+				"closed", milestone)
+		case "1.6.0":
+			assertMilestoneEqual(t, "1.6.0", "2018-09-25 07:00:00 +0000 UTC",
+				"2018-05-11 05:37:01 +0000 UTC",
+				"2019-01-27 19:21:22 +0000 UTC",
+				"2018-11-23 13:23:16 +0000 UTC",
+				"closed", milestone)
+		case "1.7.0":
+			assertMilestoneEqual(t, "1.7.0", "2018-12-25 08:00:00 +0000 UTC",
+				"2018-08-28 14:20:14 +0000 UTC",
+				"2019-01-27 11:30:24 +0000 UTC",
+				"2019-01-23 08:58:23 +0000 UTC",
+				"closed", milestone)
+		}
+	}
+
+	labels, err := downloader.GetLabels()
+	assert.NoError(t, err)
+	assert.True(t, len(labels) >= 48)
+	for _, l := range labels {
+		switch l.Name {
+		case "backport/v1.7":
+			assertLabelEqual(t, "backport/v1.7", "fbca04", l)
+		case "backport/v1.8":
+			assertLabelEqual(t, "backport/v1.8", "fbca04", l)
+		case "kind/api":
+			assertLabelEqual(t, "kind/api", "5319e7", l)
+		case "kind/breaking":
+			assertLabelEqual(t, "kind/breaking", "fbca04", l)
+		case "kind/bug":
+			assertLabelEqual(t, "kind/bug", "ee0701", l)
+		case "kind/docs":
+			assertLabelEqual(t, "kind/docs", "c2e0c6", l)
+		case "kind/enhancement":
+			assertLabelEqual(t, "kind/enhancement", "84b6eb", l)
+		case "kind/feature":
+			assertLabelEqual(t, "kind/feature", "006b75", l)
+		}
+	}
+
+	releases, err := downloader.GetReleases()
+	assert.NoError(t, err)
+	assert.EqualValues(t, []*base.Release{
+		{
+			TagName:         "v0.9.99",
+			TargetCommitish: "master",
+			Name:            "fork",
+			Body:            "Forked source from Gogs into Gitea\n",
+			Created:         time.Date(2016, 10, 17, 02, 17, 59, 0, time.UTC),
+			Published:       time.Date(2016, 11, 17, 15, 37, 0, 0, time.UTC),
+		},
+	}, releases[len(releases)-1:])
+
+	// downloader.GetIssues()
+	issues, err := downloader.GetIssues(0, 3)
+	assert.NoError(t, err)
+	assert.EqualValues(t, 3, len(issues))
+	var (
+		closed1 = time.Date(2018, 10, 23, 02, 57, 43, 0, time.UTC)
+	)
+	assert.EqualValues(t, []*base.Issue{
+		{
+			Number:     6,
+			Title:      "Contribution system: History heatmap for user",
+			Content:    "Hi guys,\r\n\r\nI think that is a possible feature, a history heatmap similar to github or gitlab.\r\nActually exists a plugin called Calendar HeatMap. I used this on mine project to heat application log and worked fine here.\r\nThen, is only a idea, what you think? :)\r\n\r\nhttp://cal-heatmap.com/\r\nhttps://github.com/wa0x6e/cal-heatmap\r\n\r\nReference: https://github.com/gogits/gogs/issues/1640",
+			Milestone:  "1.7.0",
+			PosterName: "joubertredrat",
+			State:      "closed",
+			Created:    time.Date(2016, 11, 02, 18, 51, 55, 0, time.UTC),
+			Labels: []*base.Label{
+				{
+					Name:  "kind/feature",
+					Color: "006b75",
+				},
+				{
+					Name:  "kind/ui",
+					Color: "fef2c0",
+				},
+			},
+			Reactions: &base.Reactions{
+				TotalCount: 0,
+				PlusOne:    0,
+				MinusOne:   0,
+				Laugh:      0,
+				Confused:   0,
+				Heart:      0,
+				Hooray:     0,
+			},
+			Closed: &closed1,
+		},
+		{
+			Number:     7,
+			Title:      "display page revisions on wiki",
+			Content:    "Hi guys,\r\n\r\nWiki on Gogs is very fine, I liked a lot, but I think that is good idea to be possible see other revisions from page as a page history.\r\n\r\nWhat you think?\r\n\r\nReference: https://github.com/gogits/gogs/issues/2991",
+			Milestone:  "1.x.x",
+			PosterName: "joubertredrat",
+			State:      "open",
+			Created:    time.Date(2016, 11, 02, 18, 57, 32, 0, time.UTC),
+			Labels: []*base.Label{
+				{
+					Name:  "kind/feature",
+					Color: "006b75",
+				},
+				{
+					Name:        "reviewed/confirmed",
+					Color:       "8d9b12",
+					Description: "Issue has been reviewed and confirmed to be present or accepted to be implemented",
+				},
+			},
+			Reactions: &base.Reactions{
+				TotalCount: 6,
+				PlusOne:    5,
+				MinusOne:   0,
+				Laugh:      0,
+				Confused:   1,
+				Heart:      0,
+				Hooray:     0,
+			},
+		},
+		{
+			Number:     8,
+			Title:      "audit logs",
+			Content:    "Hi,\r\n\r\nI think that is good idea to have user operation log to admin see what the user is doing at Gogs. Similar to example below\r\n\r\n| user | operation | information |\r\n| --- | --- | --- |\r\n| joubertredrat | repo.create | Create repo MyProjectData |\r\n| joubertredrat | user.settings | Edit settings |\r\n| tboerger | repo.fork | Create Fork from MyProjectData to ForkMyProjectData |\r\n| bkcsoft | repo.remove | Remove repo MySource |\r\n| tboerger | admin.auth | Edit auth LDAP org-connection |\r\n\r\nThis resource can be used on user page too, as user activity, set that log row is public (repo._) or private (user._, admin.*) and display only public activity.\r\n\r\nWhat you think?\r\n\r\n[Chat summary from March 14, 2017](https://github.com/go-gitea/gitea/issues/8#issuecomment-286463807)\r\n\r\nReferences:\r\nhttps://github.com/gogits/gogs/issues/3016",
+			Milestone:  "1.x.x",
+			PosterName: "joubertredrat",
+			State:      "open",
+			Created:    time.Date(2016, 11, 02, 18, 59, 20, 0, time.UTC),
+			Labels: []*base.Label{
+				{
+					Name:  "kind/feature",
+					Color: "006b75",
+				},
+				{
+					Name:  "kind/proposal",
+					Color: "5319e7",
+				},
+			},
+			Reactions: &base.Reactions{
+				TotalCount: 9,
+				PlusOne:    8,
+				MinusOne:   0,
+				Laugh:      0,
+				Confused:   0,
+				Heart:      1,
+				Hooray:     0,
+			},
+		},
+	}, issues)
+
+	// downloader.GetComments()
+	comments, err := downloader.GetComments(6)
+	assert.NoError(t, err)
+	assert.EqualValues(t, 35, len(comments))
+	assert.EqualValues(t, []*base.Comment{
+		{
+			PosterName: "bkcsoft",
+			Created:    time.Date(2016, 11, 02, 18, 59, 48, 0, time.UTC),
+			Content: `I would prefer a solution that is in the backend, unless it's required to have it update without reloading. Unfortunately I can't seem to find anything that does that :unamused: 
+
+Also this would _require_ caching, since it will fetch huge amounts of data from disk...
+`,
+			Reactions: &base.Reactions{
+				TotalCount: 2,
+				PlusOne:    2,
+				MinusOne:   0,
+				Laugh:      0,
+				Confused:   0,
+				Heart:      0,
+				Hooray:     0,
+			},
+		},
+		{
+			PosterName: "joubertredrat",
+			Created:    time.Date(2016, 11, 02, 19, 16, 56, 0, time.UTC),
+			Content: `Yes, this plugin build on front-end, with backend I don't know too, but we can consider make component for this.
+
+In my case I use ajax to get data, but build on frontend anyway
+`,
+			Reactions: &base.Reactions{
+				TotalCount: 0,
+				PlusOne:    0,
+				MinusOne:   0,
+				Laugh:      0,
+				Confused:   0,
+				Heart:      0,
+				Hooray:     0,
+			},
+		},
+		{
+			PosterName: "xinity",
+			Created:    time.Date(2016, 11, 03, 13, 04, 56, 0, time.UTC),
+			Content: `following  @bkcsoft retention strategy in cache is a must if we don't want gitea to waste ressources.
+something like in the latest 15days could be enough don't you think ?
+`,
+			Reactions: &base.Reactions{
+				TotalCount: 2,
+				PlusOne:    2,
+				MinusOne:   0,
+				Laugh:      0,
+				Confused:   0,
+				Heart:      0,
+				Hooray:     0,
+			},
+		},
+	}, comments[:3])
+
+	// downloader.GetPullRequests()
+	prs, err := downloader.GetPullRequests(0, 3)
+	assert.NoError(t, err)
+	assert.EqualValues(t, 3, len(prs))
+
+	closed1 = time.Date(2016, 11, 02, 18, 22, 21, 0, time.UTC)
+	var (
+		closed2 = time.Date(2016, 11, 03, 8, 06, 27, 0, time.UTC)
+		closed3 = time.Date(2016, 11, 02, 18, 22, 31, 0, time.UTC)
+	)
+
+	var (
+		merged1 = time.Date(2016, 11, 02, 18, 22, 21, 0, time.UTC)
+		merged2 = time.Date(2016, 11, 03, 8, 06, 27, 0, time.UTC)
+		merged3 = time.Date(2016, 11, 02, 18, 22, 31, 0, time.UTC)
+	)
+	assert.EqualValues(t, []*base.PullRequest{
+		{
+			Number:     1,
+			Title:      "Rename import paths: \"github.com/gogits/gogs\" -> \"github.com/go-gitea/gitea\"",
+			Content:    "",
+			Milestone:  "1.0.0",
+			PosterName: "andreynering",
+			State:      "closed",
+			Created:    time.Date(2016, 11, 02, 17, 01, 19, 0, time.UTC),
+			Labels: []*base.Label{
+				{
+					Name:  "kind/enhancement",
+					Color: "84b6eb",
+				},
+				{
+					Name:  "lgtm/done",
+					Color: "0e8a16",
+				},
+			},
+			PatchURL: "https://github.com/go-gitea/gitea/pull/1.patch",
+			Head: base.PullRequestBranch{
+				Ref:       "import-paths",
+				SHA:       "1b0ec3208db8501acba44a137c009a5a126ebaa9",
+				OwnerName: "andreynering",
+			},
+			Base: base.PullRequestBranch{
+				Ref:       "master",
+				SHA:       "6bcff7828f117af8d51285ce3acba01a7e40a867",
+				OwnerName: "go-gitea",
+				RepoName:  "gitea",
+			},
+			Closed:         &closed1,
+			Merged:         true,
+			MergedTime:     &merged1,
+			MergeCommitSHA: "142d35e8d2baec230ddb565d1265940d59141fab",
+		},
+		{
+			Number:     2,
+			Title:      "Fix sender of issue notifications",
+			Content:    "It is the FROM field in mailer configuration that needs be used,\r\nnot the USER field, which is for authentication.\r\n\r\nMigrated from https://github.com/gogits/gogs/pull/3616\r\n",
+			Milestone:  "1.0.0",
+			PosterName: "strk",
+			State:      "closed",
+			Created:    time.Date(2016, 11, 02, 17, 24, 19, 0, time.UTC),
+			Labels: []*base.Label{
+				{
+					Name:  "kind/bug",
+					Color: "ee0701",
+				},
+				{
+					Name:  "lgtm/done",
+					Color: "0e8a16",
+				},
+			},
+			PatchURL: "https://github.com/go-gitea/gitea/pull/2.patch",
+			Head: base.PullRequestBranch{
+				Ref:       "proper-from-on-issue-mail",
+				SHA:       "af03d00780a6ee70c58e135c6679542cde4f8d50",
+				RepoName:  "gogs",
+				OwnerName: "strk",
+				CloneURL:  "https://github.com/strk/gogs.git",
+			},
+			Base: base.PullRequestBranch{
+				Ref:       "develop",
+				SHA:       "5c5424301443ffa3659737d12de48ab1dfe39a00",
+				OwnerName: "go-gitea",
+				RepoName:  "gitea",
+			},
+			Closed:         &closed2,
+			Merged:         true,
+			MergedTime:     &merged2,
+			MergeCommitSHA: "d8de2beb5b92d02a0597ba7c7803839380666653",
+		},
+		{
+			Number:     3,
+			Title:      "Use proper url for libravatar dep",
+			Content:    "Fetch go-libravatar from its official source, rather than from an unmaintained fork\r\n",
+			Milestone:  "1.0.0",
+			PosterName: "strk",
+			State:      "closed",
+			Created:    time.Date(2016, 11, 02, 17, 34, 31, 0, time.UTC),
+			Labels: []*base.Label{
+				{
+					Name:  "kind/enhancement",
+					Color: "84b6eb",
+				},
+				{
+					Name:  "lgtm/done",
+					Color: "0e8a16",
+				},
+			},
+			PatchURL: "https://github.com/go-gitea/gitea/pull/3.patch",
+			Head: base.PullRequestBranch{
+				Ref:       "libravatar-proper-url",
+				SHA:       "d59a48a2550abd4129b96d38473941b895a4859b",
+				RepoName:  "gogs",
+				OwnerName: "strk",
+				CloneURL:  "https://github.com/strk/gogs.git",
+			},
+			Base: base.PullRequestBranch{
+				Ref:       "develop",
+				SHA:       "6bcff7828f117af8d51285ce3acba01a7e40a867",
+				OwnerName: "go-gitea",
+				RepoName:  "gitea",
+			},
+			Closed:         &closed3,
+			Merged:         true,
+			MergedTime:     &merged3,
+			MergeCommitSHA: "5c5424301443ffa3659737d12de48ab1dfe39a00",
+		},
+	}, prs)
+}
diff --git a/modules/migrations/main_test.go b/modules/migrations/main_test.go
new file mode 100644
index 000000000..a982ab3e6
--- /dev/null
+++ b/modules/migrations/main_test.go
@@ -0,0 +1,17 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Copyright 2018 Jonas Franz. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package migrations
+
+import (
+	"path/filepath"
+	"testing"
+
+	"code.gitea.io/gitea/models"
+)
+
+func TestMain(m *testing.M) {
+	models.MainTest(m, filepath.Join("..", ".."))
+}
diff --git a/modules/migrations/migrate.go b/modules/migrations/migrate.go
new file mode 100644
index 000000000..d72c86962
--- /dev/null
+++ b/modules/migrations/migrate.go
@@ -0,0 +1,205 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Copyright 2018 Jonas Franz. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package migrations
+
+import (
+	"fmt"
+
+	"code.gitea.io/gitea/models"
+	"code.gitea.io/gitea/modules/log"
+	"code.gitea.io/gitea/modules/migrations/base"
+)
+
+// MigrateOptions is equal to base.MigrateOptions
+type MigrateOptions = base.MigrateOptions
+
+var (
+	factories []base.DownloaderFactory
+)
+
+// RegisterDownloaderFactory registers a downloader factory
+func RegisterDownloaderFactory(factory base.DownloaderFactory) {
+	factories = append(factories, factory)
+}
+
+// MigrateRepository migrate repository according MigrateOptions
+func MigrateRepository(doer *models.User, ownerName string, opts base.MigrateOptions) (*models.Repository, error) {
+	var (
+		downloader base.Downloader
+		uploader   = NewGiteaLocalUploader(doer, ownerName, opts.Name)
+	)
+
+	for _, factory := range factories {
+		if match, err := factory.Match(opts); err != nil {
+			return nil, err
+		} else if match {
+			downloader, err = factory.New(opts)
+			if err != nil {
+				return nil, err
+			}
+			break
+		}
+	}
+
+	if downloader == nil {
+		opts.Wiki = true
+		opts.Milestones = false
+		opts.Labels = false
+		opts.Releases = false
+		opts.Comments = false
+		opts.Issues = false
+		opts.PullRequests = false
+		downloader = NewPlainGitDownloader(ownerName, opts.Name, opts.RemoteURL)
+		log.Trace("Will migrate from git: %s", opts.RemoteURL)
+	}
+
+	if err := migrateRepository(downloader, uploader, opts); err != nil {
+		if err1 := uploader.Rollback(); err1 != nil {
+			log.Error("rollback failed: %v", err1)
+		}
+		return nil, err
+	}
+
+	return uploader.repo, nil
+}
+
+// migrateRepository will download informations and upload to Uploader, this is a simple
+// process for small repository. For a big repository, save all the data to disk
+// before upload is better
+func migrateRepository(downloader base.Downloader, uploader base.Uploader, opts base.MigrateOptions) error {
+	repo, err := downloader.GetRepoInfo()
+	if err != nil {
+		return err
+	}
+	repo.IsPrivate = opts.Private
+	repo.IsMirror = opts.Mirror
+	log.Trace("migrating git data")
+	if err := uploader.CreateRepo(repo, opts.Wiki); err != nil {
+		return err
+	}
+
+	if opts.Milestones {
+		log.Trace("migrating milestones")
+		milestones, err := downloader.GetMilestones()
+		if err != nil {
+			return err
+		}
+
+		for _, milestone := range milestones {
+			if err := uploader.CreateMilestone(milestone); err != nil {
+				return err
+			}
+		}
+	}
+
+	if opts.Labels {
+		log.Trace("migrating labels")
+		labels, err := downloader.GetLabels()
+		if err != nil {
+			return err
+		}
+
+		for _, label := range labels {
+			if err := uploader.CreateLabel(label); err != nil {
+				return err
+			}
+		}
+	}
+
+	if opts.Releases {
+		log.Trace("migrating releases")
+		releases, err := downloader.GetReleases()
+		if err != nil {
+			return err
+		}
+
+		for _, release := range releases {
+			if err := uploader.CreateRelease(release); err != nil {
+				return err
+			}
+		}
+	}
+
+	if opts.Issues {
+		log.Trace("migrating issues and comments")
+		for {
+			issues, err := downloader.GetIssues(0, 100)
+			if err != nil {
+				return err
+			}
+			for _, issue := range issues {
+				if !opts.IgnoreIssueAuthor {
+					issue.Content = fmt.Sprintf("Author: @%s \n\n%s", issue.PosterName, issue.Content)
+				}
+
+				if err := uploader.CreateIssue(issue); err != nil {
+					return err
+				}
+
+				if !opts.Comments {
+					continue
+				}
+
+				comments, err := downloader.GetComments(issue.Number)
+				if err != nil {
+					return err
+				}
+				for _, comment := range comments {
+					if !opts.IgnoreIssueAuthor {
+						comment.Content = fmt.Sprintf("Author: @%s \n\n%s", comment.PosterName, comment.Content)
+					}
+					if err := uploader.CreateComment(issue.Number, comment); err != nil {
+						return err
+					}
+				}
+			}
+
+			if len(issues) < 100 {
+				break
+			}
+		}
+	}
+
+	if opts.PullRequests {
+		log.Trace("migrating pull requests and comments")
+		for {
+			prs, err := downloader.GetPullRequests(0, 100)
+			if err != nil {
+				return err
+			}
+
+			for _, pr := range prs {
+				if !opts.IgnoreIssueAuthor {
+					pr.Content = fmt.Sprintf("Author: @%s \n\n%s", pr.PosterName, pr.Content)
+				}
+				if err := uploader.CreatePullRequest(pr); err != nil {
+					return err
+				}
+				if !opts.Comments {
+					continue
+				}
+
+				comments, err := downloader.GetComments(pr.Number)
+				if err != nil {
+					return err
+				}
+				for _, comment := range comments {
+					if !opts.IgnoreIssueAuthor {
+						comment.Content = fmt.Sprintf("Author: @%s \n\n%s", comment.PosterName, comment.Content)
+					}
+					if err := uploader.CreateComment(pr.Number, comment); err != nil {
+						return err
+					}
+				}
+			}
+			if len(prs) < 100 {
+				break
+			}
+		}
+	}
+
+	return nil
+}
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index d2cd1e664..570498958 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -301,6 +301,8 @@ password_not_match = The passwords do not match.
 
 username_been_taken = The username is already taken.
 repo_name_been_taken = The repository name is already used.
+visit_rate_limit = Remote visit addressed rate limitation.
+2fa_auth_required = Remote visit required two factors authentication.
 org_name_been_taken = The organization name is already taken.
 team_name_been_taken = The team name is already taken.
 team_no_units_error = Allow access to at least one repository section.
@@ -597,6 +599,13 @@ form.name_pattern_not_allowed = The pattern '%s' is not allowed in a repository
 need_auth = Clone Authorization
 migrate_type = Migration Type
 migrate_type_helper = This repository will be a <span class="text blue">mirror</span>
+migrate_items = Migration Items
+migrate_items_wiki = Wiki
+migrate_items_milestones = Milestones
+migrate_items_labels = Labels
+migrate_items_issues = Issues
+migrate_items_pullrequests = Pull Requests
+migrate_items_releases = Releases
 migrate_repo = Migrate Repository
 migrate.clone_address = Migrate / Clone From URL
 migrate.clone_address_desc = The HTTP(S) or Git 'clone' URL of an existing repository
@@ -605,6 +614,7 @@ migrate.permission_denied = You are not allowed to import local repositories.
 migrate.invalid_local_path = "The local path is invalid. It does not exist or is not a directory."
 migrate.failed = Migration failed: %v
 migrate.lfs_mirror_unsupported = Mirroring LFS objects is not supported - use 'git lfs fetch --all' and 'git lfs push --all' instead.
+migrate.migrate_items_options = When you are migrating from github and inputed username, the migration options will be display.
 
 mirror_from = mirror of
 forked_from = forked from
diff --git a/public/js/index.js b/public/js/index.js
index 9a9052eba..79d0569f9 100644
--- a/public/js/index.js
+++ b/public/js/index.js
@@ -979,6 +979,25 @@ function initRepository() {
     }
 }
 
+var toggleMigrations = function(){
+    var authUserName = $('#auth_username').val();
+    var cloneAddr = $('#clone_addr').val();
+    if (!$('#mirror').is(":checked") && (authUserName!=undefined && authUserName.length > 0) 
+    && (cloneAddr!=undefined && (cloneAddr.startsWith("https://github.com") || cloneAddr.startsWith("http://github.com")))) {
+        $('#migrate_items').show();
+    } else {
+        $('#migrate_items').hide();
+    }
+}
+
+function initMigration() {
+    toggleMigrations();
+
+    $('#clone_addr').on('input', toggleMigrations)
+    $('#auth_username').on('input', toggleMigrations)
+    $('#mirror').on('change', toggleMigrations)
+}
+
 function initPullRequestReview() {
     $('.show-outdated').on('click', function (e) {
         e.preventDefault();
@@ -2101,6 +2120,7 @@ $(document).ready(function () {
     initCommentForm();
     initInstall();
     initRepository();
+    initMigration();
     initWikiForm();
     initEditForm();
     initEditor();
diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go
index 1991ed596..35fea20d4 100644
--- a/routers/api/v1/repo/repo.go
+++ b/routers/api/v1/repo/repo.go
@@ -14,6 +14,7 @@ import (
 	"code.gitea.io/gitea/modules/auth"
 	"code.gitea.io/gitea/modules/context"
 	"code.gitea.io/gitea/modules/log"
+	"code.gitea.io/gitea/modules/migrations"
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/util"
 	"code.gitea.io/gitea/routers/api/v1/convert"
@@ -401,31 +402,63 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) {
 		return
 	}
 
-	repo, err := models.MigrateRepository(ctx.User, ctxUser, models.MigrateRepoOptions{
-		Name:        form.RepoName,
-		Description: form.Description,
-		IsPrivate:   form.Private || setting.Repository.ForcePrivate,
-		IsMirror:    form.Mirror,
-		RemoteAddr:  remoteAddr,
-	})
-	if err != nil {
-		if models.IsErrRepoAlreadyExist(err) {
-			ctx.Error(409, "", "The repository with the same name already exists.")
-			return
-		}
+	var opts = migrations.MigrateOptions{
+		RemoteURL:    remoteAddr,
+		Name:         form.RepoName,
+		Description:  form.Description,
+		Private:      form.Private || setting.Repository.ForcePrivate,
+		Mirror:       form.Mirror,
+		AuthUsername: form.AuthUsername,
+		AuthPassword: form.AuthPassword,
+		Wiki:         form.Wiki,
+		Issues:       form.Issues,
+		Milestones:   form.Milestones,
+		Labels:       form.Labels,
+		Comments:     true,
+		PullRequests: form.PullRequests,
+		Releases:     form.Releases,
+	}
+	if opts.Mirror {
+		opts.Issues = false
+		opts.Milestones = false
+		opts.Labels = false
+		opts.Comments = false
+		opts.PullRequests = false
+		opts.Releases = false
+	}
 
-		err = util.URLSanitizedError(err, remoteAddr)
-		if repo != nil {
-			if errDelete := models.DeleteRepository(ctx.User, ctxUser.ID, repo.ID); errDelete != nil {
-				log.Error("DeleteRepository: %v", errDelete)
-			}
-		}
-		ctx.Error(500, "MigrateRepository", err)
+	repo, err := migrations.MigrateRepository(ctx.User, ctxUser.Name, opts)
+	if err == nil {
+		log.Trace("Repository migrated: %s/%s", ctxUser.Name, form.RepoName)
+		ctx.JSON(201, repo.APIFormat(models.AccessModeAdmin))
 		return
 	}
 
-	log.Trace("Repository migrated: %s/%s", ctxUser.Name, form.RepoName)
-	ctx.JSON(201, repo.APIFormat(models.AccessModeAdmin))
+	switch {
+	case models.IsErrRepoAlreadyExist(err):
+		ctx.Error(409, "", "The repository with the same name already exists.")
+	case migrations.IsRateLimitError(err):
+		ctx.Error(422, "", "Remote visit addressed rate limitation.")
+	case migrations.IsTwoFactorAuthError(err):
+		ctx.Error(422, "", "Remote visit required two factors authentication.")
+	case models.IsErrReachLimitOfRepo(err):
+		ctx.Error(422, "", fmt.Sprintf("You have already reached your limit of %d repositories.", ctxUser.MaxCreationLimit()))
+	case models.IsErrNameReserved(err):
+		ctx.Error(422, "", fmt.Sprintf("The username '%s' is reserved.", err.(models.ErrNameReserved).Name))
+	case models.IsErrNamePatternNotAllowed(err):
+		ctx.Error(422, "", fmt.Sprintf("The pattern '%s' is not allowed in a username.", err.(models.ErrNamePatternNotAllowed).Pattern))
+	default:
+		err = util.URLSanitizedError(err, remoteAddr)
+		if strings.Contains(err.Error(), "Authentication failed") ||
+			strings.Contains(err.Error(), "Bad credentials") ||
+			strings.Contains(err.Error(), "could not read Username") {
+			ctx.Error(422, "", fmt.Sprintf("Authentication failed: %v.", err))
+		} else if strings.Contains(err.Error(), "fatal:") {
+			ctx.Error(422, "", fmt.Sprintf("Migration failed: %v.", err))
+		} else {
+			ctx.Error(500, "MigrateRepository", err)
+		}
+	}
 }
 
 // Get one repository
diff --git a/routers/repo/repo.go b/routers/repo/repo.go
index 5588b07e2..49483a64e 100644
--- a/routers/repo/repo.go
+++ b/routers/repo/repo.go
@@ -16,6 +16,7 @@ import (
 	"code.gitea.io/gitea/modules/context"
 	"code.gitea.io/gitea/modules/git"
 	"code.gitea.io/gitea/modules/log"
+	"code.gitea.io/gitea/modules/migrations"
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/util"
 
@@ -130,6 +131,8 @@ func Create(ctx *context.Context) {
 
 func handleCreateError(ctx *context.Context, owner *models.User, err error, name string, tpl base.TplName, form interface{}) {
 	switch {
+	case migrations.IsRateLimitError(err):
+		ctx.RenderWithErr(ctx.Tr("form.visit_rate_limit"), tpl, form)
 	case models.IsErrReachLimitOfRepo(err):
 		ctx.RenderWithErr(ctx.Tr("repo.form.reach_limit_of_creation", owner.MaxCreationLimit()), tpl, form)
 	case models.IsErrRepoAlreadyExist(err):
@@ -195,6 +198,12 @@ func Migrate(ctx *context.Context) {
 	ctx.Data["private"] = getRepoPrivate(ctx)
 	ctx.Data["IsForcedPrivate"] = setting.Repository.ForcePrivate
 	ctx.Data["mirror"] = ctx.Query("mirror") == "1"
+	ctx.Data["wiki"] = ctx.Query("wiki") == "1"
+	ctx.Data["milestones"] = ctx.Query("milestones") == "1"
+	ctx.Data["labels"] = ctx.Query("labels") == "1"
+	ctx.Data["issues"] = ctx.Query("issues") == "1"
+	ctx.Data["pull_requests"] = ctx.Query("pull_requests") == "1"
+	ctx.Data["releases"] = ctx.Query("releases") == "1"
 	ctx.Data["LFSActive"] = setting.LFS.StartServer
 
 	ctxUser := checkContextUser(ctx, ctx.QueryInt64("org"))
@@ -242,45 +251,70 @@ func MigratePost(ctx *context.Context, form auth.MigrateRepoForm) {
 		return
 	}
 
-	repo, err := models.MigrateRepository(ctx.User, ctxUser, models.MigrateRepoOptions{
-		Name:        form.RepoName,
-		Description: form.Description,
-		IsPrivate:   form.Private || setting.Repository.ForcePrivate,
-		IsMirror:    form.Mirror,
-		RemoteAddr:  remoteAddr,
-	})
+	var opts = migrations.MigrateOptions{
+		RemoteURL:    remoteAddr,
+		Name:         form.RepoName,
+		Description:  form.Description,
+		Private:      form.Private || setting.Repository.ForcePrivate,
+		Mirror:       form.Mirror,
+		AuthUsername: form.AuthUsername,
+		AuthPassword: form.AuthPassword,
+		Wiki:         form.Wiki,
+		Issues:       form.Issues,
+		Milestones:   form.Milestones,
+		Labels:       form.Labels,
+		Comments:     true,
+		PullRequests: form.PullRequests,
+		Releases:     form.Releases,
+	}
+	if opts.Mirror {
+		opts.Issues = false
+		opts.Milestones = false
+		opts.Labels = false
+		opts.Comments = false
+		opts.PullRequests = false
+		opts.Releases = false
+	}
+
+	repo, err := migrations.MigrateRepository(ctx.User, ctxUser.Name, opts)
 	if err == nil {
-		log.Trace("Repository migrated [%d]: %s/%s", repo.ID, ctxUser.Name, form.RepoName)
+		log.Trace("Repository migrated [%d]: %s/%s successfully", repo.ID, ctxUser.Name, form.RepoName)
 		ctx.Redirect(setting.AppSubURL + "/" + ctxUser.Name + "/" + form.RepoName)
 		return
 	}
 
-	if models.IsErrRepoAlreadyExist(err) {
+	switch {
+	case models.IsErrReachLimitOfRepo(err):
+		ctx.RenderWithErr(ctx.Tr("repo.form.reach_limit_of_creation", ctxUser.MaxCreationLimit()), tplMigrate, &form)
+	case models.IsErrNameReserved(err):
+		ctx.Data["Err_RepoName"] = true
+		ctx.RenderWithErr(ctx.Tr("repo.form.name_reserved", err.(models.ErrNameReserved).Name), tplMigrate, &form)
+	case models.IsErrRepoAlreadyExist(err):
+		ctx.Data["Err_RepoName"] = true
 		ctx.RenderWithErr(ctx.Tr("form.repo_name_been_taken"), tplMigrate, &form)
-		return
-	}
-
-	// remoteAddr may contain credentials, so we sanitize it
-	err = util.URLSanitizedError(err, remoteAddr)
-
-	if repo != nil {
-		if errDelete := models.DeleteRepository(ctx.User, ctxUser.ID, repo.ID); errDelete != nil {
-			log.Error("DeleteRepository: %v", errDelete)
+	case models.IsErrNamePatternNotAllowed(err):
+		ctx.Data["Err_RepoName"] = true
+		ctx.RenderWithErr(ctx.Tr("repo.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), tplMigrate, &form)
+	case migrations.IsRateLimitError(err):
+		ctx.RenderWithErr(ctx.Tr("form.visit_rate_limit"), tplMigrate, &form)
+	case migrations.IsTwoFactorAuthError(err):
+		ctx.Data["Err_Auth"] = true
+		ctx.RenderWithErr(ctx.Tr("form.2fa_auth_required"), tplMigrate, &form)
+	default:
+		// remoteAddr may contain credentials, so we sanitize it
+		err = util.URLSanitizedError(err, remoteAddr)
+		if strings.Contains(err.Error(), "Authentication failed") ||
+			strings.Contains(err.Error(), "Bad credentials") ||
+			strings.Contains(err.Error(), "could not read Username") {
+			ctx.Data["Err_Auth"] = true
+			ctx.RenderWithErr(ctx.Tr("form.auth_failed", err.Error()), tplMigrate, &form)
+		} else if strings.Contains(err.Error(), "fatal:") {
+			ctx.Data["Err_CloneAddr"] = true
+			ctx.RenderWithErr(ctx.Tr("repo.migrate.failed", err.Error()), tplMigrate, &form)
+		} else {
+			ctx.ServerError("MigratePost", err)
 		}
 	}
-
-	if strings.Contains(err.Error(), "Authentication failed") ||
-		strings.Contains(err.Error(), "could not read Username") {
-		ctx.Data["Err_Auth"] = true
-		ctx.RenderWithErr(ctx.Tr("form.auth_failed", err.Error()), tplMigrate, &form)
-		return
-	} else if strings.Contains(err.Error(), "fatal:") {
-		ctx.Data["Err_CloneAddr"] = true
-		ctx.RenderWithErr(ctx.Tr("repo.migrate.failed", err.Error()), tplMigrate, &form)
-		return
-	}
-
-	handleCreateError(ctx, ctxUser, err, "MigratePost", tplMigrate, &form)
 }
 
 // Action response for actions to a repository
diff --git a/templates/repo/migrate.tmpl b/templates/repo/migrate.tmpl
index 509463e91..f30b59df3 100644
--- a/templates/repo/migrate.tmpl
+++ b/templates/repo/migrate.tmpl
@@ -14,6 +14,7 @@
 						<input id="clone_addr" name="clone_addr" value="{{.clone_addr}}" autofocus required>
 						<span class="help">
 						{{.i18n.Tr "repo.migrate.clone_address_desc"}}{{if .ContextUser.CanImportLocal}} {{.i18n.Tr "repo.migrate.clone_local_path"}}{{end}}
+						<br/>{{.i18n.Tr "repo.migrate.migrate_items_options"}}
 						{{if .LFSActive}}<br/>{{.i18n.Tr "repo.migrate.lfs_mirror_unsupported"}}{{end}}
 						</span>
 					</div>
@@ -80,10 +81,45 @@
 					<div class="inline field">
 						<label>{{.i18n.Tr "repo.migrate_type"}}</label>
 						<div class="ui checkbox">
-							<input name="mirror" type="checkbox" {{if .mirror}}checked{{end}}>
+							<input id="mirror" name="mirror" type="checkbox" {{if .mirror}}checked{{end}}>
 							<label>{{.i18n.Tr "repo.migrate_type_helper" | Safe}}</label>
 						</div>
 					</div>
+					<div id="migrate_items" class="ui field">
+						<div class="inline field">
+							<label>{{.i18n.Tr "repo.migrate_items"}}</label>
+							<div class="ui checkbox">
+								<input name="wiki" type="checkbox" {{if .wiki}}checked{{end}}>
+								<label>{{.i18n.Tr "repo.migrate_items_wiki" | Safe}}</label>
+							</div>
+							<div class="ui checkbox">
+								<input name="milestones" type="checkbox" {{if .milestones}}checked{{end}}>
+								<label>{{.i18n.Tr "repo.migrate_items_milestones" | Safe}}</label>
+							</div>
+						</div>
+						<div class="inline field">
+							<label></label>
+							<div class="ui checkbox">
+								<input name="labels" type="checkbox" {{if .labels}}checked{{end}}>
+								<label>{{.i18n.Tr "repo.migrate_items_labels" | Safe}}</label>
+							</div>
+							<div class="ui checkbox">
+								<input name="issues" type="checkbox" {{if .issues}}checked{{end}}>
+								<label>{{.i18n.Tr "repo.migrate_items_issues" | Safe}}</label>
+							</div>
+						</div>
+						<div class="inline field">
+							<label></label>
+							<div class="ui checkbox">
+								<input name="pull_requests" type="checkbox" {{if .pull_requests}}checked{{end}}>
+								<label>{{.i18n.Tr "repo.migrate_items_pullrequests" | Safe}}</label>
+							</div>
+							<div class="ui checkbox">
+								<input name="releases" type="checkbox" {{if .releases}}checked{{end}}>
+								<label>{{.i18n.Tr "repo.migrate_items_releases" | Safe}}</label>
+							</div>
+						</div>
+					</div>
 					<div class="inline field {{if .Err_Description}}error{{end}}">
 						<label for="description">{{.i18n.Tr "repo.repo_desc"}}</label>
 						<textarea id="description" name="description">{{.description}}</textarea>
diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl
index 134b9051b..bc095f723 100644
--- a/templates/swagger/v1_json.tmpl
+++ b/templates/swagger/v1_json.tmpl
@@ -8479,6 +8479,18 @@
           "type": "string",
           "x-go-name": "Description"
         },
+        "issues": {
+          "type": "boolean",
+          "x-go-name": "Issues"
+        },
+        "labels": {
+          "type": "boolean",
+          "x-go-name": "Labels"
+        },
+        "milestones": {
+          "type": "boolean",
+          "x-go-name": "Milestones"
+        },
         "mirror": {
           "type": "boolean",
           "x-go-name": "Mirror"
@@ -8487,6 +8499,14 @@
           "type": "boolean",
           "x-go-name": "Private"
         },
+        "pull_requests": {
+          "type": "boolean",
+          "x-go-name": "PullRequests"
+        },
+        "releases": {
+          "type": "boolean",
+          "x-go-name": "Releases"
+        },
         "repo_name": {
           "type": "string",
           "x-go-name": "RepoName"
@@ -8495,6 +8515,10 @@
           "type": "integer",
           "format": "int64",
           "x-go-name": "UID"
+        },
+        "wiki": {
+          "type": "boolean",
+          "x-go-name": "Wiki"
         }
       },
       "x-go-package": "code.gitea.io/gitea/modules/auth"
diff --git a/vendor/github.com/google/go-github/v24/AUTHORS b/vendor/github.com/google/go-github/v24/AUTHORS
new file mode 100644
index 000000000..1bde5b1f5
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/AUTHORS
@@ -0,0 +1,229 @@
+# This is the official list of go-github authors for copyright purposes.
+#
+# This does not necessarily list everyone who has contributed code, since in
+# some cases, their employer may be the copyright holder. To see the full list
+# of contributors, see the revision history in source control or
+# https://github.com/google/go-github/graphs/contributors.
+#
+# Authors who wish to be recognized in this file should add themselves (or
+# their employer, as appropriate).
+
+178inaba <masahiro.furudate@gmail.com>
+Abhinav Gupta <mail@abhinavg.net>
+Ahmed Hagy <a.akram93@gmail.com>
+Ainsley Chong <ainsley.chong@gmail.com>
+Akeda Bagus <akeda@x-team.com>
+Akhil Mohan <akhilerm@gmail.com>
+Alec Thomas <alec@swapoff.org>
+Aleks Clark <aleks.clark@gmail.com>
+Alex Bramley <a.bramley@gmail.com>
+Alexander Harkness <me@bearbin.net>
+Allen Sun <shlallen1990@gmail.com>
+Amey Sakhadeo <me@ameyms.com>
+Andreas Garnæs <https://github.com/andreas>
+Andrew Ryabchun <aryabchun@mail.ua>
+Andy Grunwald <andygrunwald@gmail.com>
+Andy Hume <andyhume@gmail.com>
+Andy Lindeman <andy@lindeman.io>
+Anshuman Bhartiya <anshuman.bhartiya@gmail.com>
+Antoine <antoine.tu@mail.mcgill.ca>
+Antoine Pelisse <apelisse@gmail.com>
+Anubha Kushwaha <anubha_bt2k14@dtu.ac.in>
+appilon <apilon@hashicorp.com>
+Aravind <aravindkp@outlook.in>
+Arda Kuyumcu <kuyumcuarda@gmail.com>
+Arıl Bozoluk <arilbozoluk@hotmail.com>
+Austin Dizzy <dizzy@wow.com>
+Ben Batha <bhbatha@gmail.com>
+Benjamen Keroack <benjamen@dollarshaveclub.com>
+Beshr Kayali <beshrkayali@gmail.com>
+Beyang Liu <beyang.liu@gmail.com>
+Billy Lynch <wlynch92@gmail.com>
+Björn Häuser <b.haeuser@rebuy.de>
+Brad Harris <bmharris@gmail.com>
+Brad Moylan <moylan.brad@gmail.com>
+Bradley Falzon <brad@teambrad.net>
+Brandon Cook <phylake@gmail.com>
+Brian Egizi <brian@mojotech.com>
+Bryan Boreham <bryan@weave.works>
+Cami Diez <diezcami@gmail.com>
+Carlos Alexandro Becker <caarlos0@gmail.com>
+chandresh-pancholi <chandreshpancholi007@gmail.com>
+Charles Fenwick Elliott <Charles@FenwickElliott.io>
+Charlie Yan <charlieyan08@gmail.com>
+Chris King <chriskingnet@gmail.com>
+Chris Roche <chris@vsco.co>
+Chris Schaefer <chris@dtzq.com>
+Christoph Sassenberg <defsprite@gmail.com>
+Colin Misare <github.com/cmisare>
+Craig Peterson <cpeterson@stackoverflow.com>
+Cristian Maglie <c.maglie@bug.st>
+Daehyeok Mun <daehyeok@gmail.com>
+Daniel Leavitt <daniel.leavitt@gmail.com>
+Daniel Nilsson <daniel.nilsson1989@gmail.com>
+Dave Du Cros <davidducros@gmail.com>
+Dave Henderson <dhenderson@gmail.com>
+David Deng <daviddengcn@gmail.com>
+David Jannotta <djannotta@gmail.com>
+Davide Zipeto <dawez1@gmail.com>
+Dennis Webb <dennis@bluesentryit.com>
+Dhi Aurrahman <diorahman@rockybars.com>
+Diego Lapiduz <diego.lapiduz@cfpb.gov>
+Dmitri Shuralyov <shurcooL@gmail.com>
+dmnlk <seikima2demon@gmail.com>
+Don Petersen <don@donpetersen.net>
+Doug Turner <doug.turner@gmail.com>
+Drew Fradette <drew.fradette@gmail.com>
+Eli Uriegas <seemethere101@gmail.com>
+Elliott Beach <elliott2.71828@gmail.com>
+Emerson Wood <emersonwood94@gmail.com>
+eperm <staffordworrell@gmail.com>
+Erick Fejta <erick@fejta.com>
+erwinvaneyk <erwinvaneyk@gmail.com>
+Fabrice <fabrice.vaillant@student.ecp.fr>
+Felix Geisendörfer <felix@debuggable.com>
+Filippo Valsorda <hi@filippo.io>
+Florian Forster <ff@octo.it>
+Francesc Gil <xescugil@gmail.com>
+Francis <hello@francismakes.com>
+Fredrik Jönsson <fredrik.jonsson@izettle.com>
+Garrett Squire <garrettsquire@gmail.com>
+George Kontridze <george.kontridze@gmail.com>
+Georgy Buranov <gburanov@gmail.com>
+Gnahz <p@oath.pl>
+Google Inc.
+Grachev Mikhail <work@mgrachev.com>
+griffin_stewie <panterathefamilyguy@gmail.com>
+Guillaume Jacquet <guillaume.jacquet@gmail.com>
+Guz Alexander <kalimatas@gmail.com>
+Guðmundur Bjarni Ólafsson <gudmundur@github.com>
+Hanno Hecker <hanno.hecker@zalando.de>
+Hari haran <hariharan.uno@gmail.com>
+haya14busa <hayabusa1419@gmail.com>
+Huy Tr <kingbazoka@gmail.com>
+huydx <doxuanhuy@gmail.com>
+i2bskn <i2bskn@gmail.com>
+Isao Jonas <isao.jonas@gmail.com>
+isqua <isqua@isqua.ru>
+Jameel Haffejee <RC1140@republiccommandos.co.za>
+Jan Kosecki <jan.kosecki91@gmail.com>
+Javier Campanini <jcampanini@palantir.com>
+Jens Rantil <jens.rantil@gmail.com>
+Jeremy Morris <jeremylevanmorris@gmail.com>
+Jesse Newland <jesse@jnewland.com>
+Jihoon Chung <j.c@navercorp.com>
+Jimmi Dyson <jimmidyson@gmail.com>
+Joan Saum <joan.saum@epitech.eu>
+Joe Tsai <joetsai@digital-static.net>
+John Barton <jrbarton@gmail.com>
+John Engelman <john.r.engelman@gmail.com>
+Jordan Sussman <jordansail22@gmail.com>
+Joshua Bezaleel Abednego <joshua.bezaleel@gmail.com>
+JP Phillips <jonphill9@gmail.com>
+jpbelanger-mtl <jp.belanger@gmail.com>
+Juan Basso <jrbasso@gmail.com>
+Julien Garcia Gonzalez <garciagonzalez.julien@gmail.com>
+Julien Rostand <jrostand@users.noreply.github.com>
+Justin Abrahms <justin@abrah.ms>
+Jusung Lee <e.jusunglee@gmail.com>
+jzhoucliqr <jzhou@cliqr.com>
+Katrina Owen <kytrinyx@github.com>
+Kautilya Tripathi < tripathi.kautilya@gmail.com>
+Kautilya Tripathi <tripathi.kautilya@gmail.com>
+Keita Urashima <ursm@ursm.jp>
+Kevin Burke <kev@inburke.com>
+Konrad Malawski <konrad.malawski@project13.pl>
+Kookheon Kwon <kucuny@gmail.com>
+Krzysztof Kowalczyk <kkowalczyk@gmail.com>
+Kshitij Saraogi <KshitijSaraogi@gmail.com>
+kyokomi <kyoko1220adword@gmail.com>
+Lovro Mažgon <lovro.mazgon@gmail.com>
+Lucas Alcantara <lucasalcantaraf@gmail.com>
+Luke Evers <me@lukevers.com>
+Luke Kysow <lkysow@gmail.com>
+Luke Roberts <email@luke-roberts.co.uk>
+Luke Young <luke@hydrantlabs.org>
+Maksim Zhylinski <uzzable@gmail.com>
+Martin-Louis Bright <mlbright@gmail.com>
+Marwan Sulaiman <marwan.sameer@gmail.com>
+Mat Geist <matgeist@gmail.com>
+Matt <alpmatthew@gmail.com>
+Matt Brender <mjbrender@gmail.com>
+Matt Gaunt <matt@gauntface.co.uk>
+Matt Landis <landis.matt@gmail.com>
+Maxime Bury <maxime.bury@gmail.com>
+Michael Spiegel <michael.m.spiegel@gmail.com>
+Michael Tiller <michael.tiller@gmail.com>
+Michał Glapa <michal.glapa@gmail.com>
+Nathan VanBenschoten <nvanbenschoten@gmail.com>
+Navaneeth Suresh <navaneeths1998@gmail.com>
+Neil O'Toole <neilotoole@apache.org>
+Nick Miyake <nmiyake@palantir.com>
+Nick Spragg <nick.spragg@bbc.co.uk>
+Nikhita Raghunath <nikitaraghunath@gmail.com>
+Noah Zoschke <noah+sso2@convox.com>
+ns-cweber <cweber@narrativescience.com>
+Oleg Kovalov <iamolegkovalov@gmail.com>
+Ondřej Kupka <ondra.cap@gmail.com>
+Palash Nigam <npalash25@gmail.com>
+Panagiotis Moustafellos <pmoust@gmail.com>
+Parham Alvani <parham.alvani@gmail.com>
+Parker Moore <parkrmoore@gmail.com>
+parkhyukjun89 <park.hyukjun89@gmail.com>
+Pavel Shtanko <pavel.shtanko@gmail.com>
+Pete Wagner <thepwagner@github.com>
+Petr Shevtsov <petr.shevtsov@gmail.com>
+Pierre Carrier <pierre@meteor.com>
+Piotr Zurek <p.zurek@gmail.com>
+Quinn Slack <qslack@qslack.com>
+Rackspace US, Inc.
+Radek Simko <radek.simko@gmail.com>
+Radliński Ignacy <radlinsk@student.agh.edu.pl>
+Rajendra arora <rajendraarora16@yahoo.com>
+RaviTeja Pothana <ravi-teja@live.com>
+rc1140 <jameel@republiccommandos.co.za>
+Red Hat, Inc.
+Rob Figueiredo <robfig@yext.com>
+Rohit Upadhyay <urohit011@gmail.com>
+Ronak Jain <ronakjain@outlook.in>
+Ruben Vereecken <rubenvereecken@gmail.com>
+Ryan Leung <rleungx@gmail.com>
+Ryan Lower <rpjlower@gmail.com>
+Sahil Dua <sahildua2305@gmail.com>
+saisi <saisi@users.noreply.github.com>
+Sam Minnée <sam@silverstripe.com>
+Sandeep Sukhani <sandeep.d.sukhani@gmail.com>
+Sander van Harmelen <svanharmelen@schubergphilis.com>
+Sanket Payghan <sanket.payghan8@gmail.com>
+Sarasa Kisaragi <lingsamuelgrace@gmail.com>
+Sean Wang <sean@decrypted.org>
+Sebastian Mandrean <sebastian.mandrean@gmail.com>
+Sebastian Mæland Pedersen <sem.pedersen@stud.uis.no>
+Sergey Romanov <xxsmotur@gmail.com>
+Sevki <s@sevki.org>
+Shagun Khemka <shagun.khemka60@gmail.com>
+shakeelrao <shakeelrao79@gmail.com>
+Shawn Catanzarite <me@shawncatz.com>
+Shawn Smith <shawnpsmith@gmail.com>
+sona-tar <sona.zip@gmail.com>
+SoundCloud, Ltd.
+Sridhar Mocherla <srmocher@microsoft.com>
+Stian Eikeland <stian@eikeland.se>
+Tasya Aditya Rukmana <tadityar@gmail.com>
+Thomas Bruyelle <thomas.bruyelle@gmail.com>
+Timothée Peignier <timothee.peignier@tryphon.org>
+Trey Tacon <ttacon@gmail.com>
+ttacon <ttacon@gmail.com>
+Varadarajan Aravamudhan <varadaraajan@gmail.com>
+Victor Castell <victor@victorcastell.com>
+Victor Vrantchan <vrancean+github@gmail.com>
+Vlad Ungureanu <vladu@palantir.com>
+Wasim Thabraze <wasim@thabraze.me>
+Will Maier <wcmaier@gmail.com>
+William Bailey <mail@williambailey.org.uk>
+xibz <impactbchang@gmail.com>
+Yann Malet <yann.malet@gmail.com>
+Yannick Utard <yannickutard@gmail.com>
+Yicheng Qin <qycqycqycqycqyc@gmail.com>
+Yumikiyo Osanai <yumios.art@gmail.com>
+Zach Latta <zach@zachlatta.com>
diff --git a/vendor/github.com/google/go-github/v24/LICENSE b/vendor/github.com/google/go-github/v24/LICENSE
new file mode 100644
index 000000000..28b6486f0
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2013 The go-github AUTHORS. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/google/go-github/v24/github/activity.go b/vendor/github.com/google/go-github/v24/github/activity.go
new file mode 100644
index 000000000..d6c992c7f
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/activity.go
@@ -0,0 +1,69 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import "context"
+
+// ActivityService handles communication with the activity related
+// methods of the GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/
+type ActivityService service
+
+// FeedLink represents a link to a related resource.
+type FeedLink struct {
+	HRef *string `json:"href,omitempty"`
+	Type *string `json:"type,omitempty"`
+}
+
+// Feeds represents timeline resources in Atom format.
+type Feeds struct {
+	TimelineURL                 *string  `json:"timeline_url,omitempty"`
+	UserURL                     *string  `json:"user_url,omitempty"`
+	CurrentUserPublicURL        *string  `json:"current_user_public_url,omitempty"`
+	CurrentUserURL              *string  `json:"current_user_url,omitempty"`
+	CurrentUserActorURL         *string  `json:"current_user_actor_url,omitempty"`
+	CurrentUserOrganizationURL  *string  `json:"current_user_organization_url,omitempty"`
+	CurrentUserOrganizationURLs []string `json:"current_user_organization_urls,omitempty"`
+	Links                       *struct {
+		Timeline                 *FeedLink  `json:"timeline,omitempty"`
+		User                     *FeedLink  `json:"user,omitempty"`
+		CurrentUserPublic        *FeedLink  `json:"current_user_public,omitempty"`
+		CurrentUser              *FeedLink  `json:"current_user,omitempty"`
+		CurrentUserActor         *FeedLink  `json:"current_user_actor,omitempty"`
+		CurrentUserOrganization  *FeedLink  `json:"current_user_organization,omitempty"`
+		CurrentUserOrganizations []FeedLink `json:"current_user_organizations,omitempty"`
+	} `json:"_links,omitempty"`
+}
+
+// ListFeeds lists all the feeds available to the authenticated user.
+//
+// GitHub provides several timeline resources in Atom format:
+//     Timeline: The GitHub global public timeline
+//     User: The public timeline for any user, using URI template
+//     Current user public: The public timeline for the authenticated user
+//     Current user: The private timeline for the authenticated user
+//     Current user actor: The private timeline for activity created by the
+//         authenticated user
+//     Current user organizations: The private timeline for the organizations
+//         the authenticated user is a member of.
+//
+// Note: Private feeds are only returned when authenticating via Basic Auth
+// since current feed URIs use the older, non revocable auth tokens.
+func (s *ActivityService) ListFeeds(ctx context.Context) (*Feeds, *Response, error) {
+	req, err := s.client.NewRequest("GET", "feeds", nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	f := &Feeds{}
+	resp, err := s.client.Do(ctx, req, f)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return f, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/activity_events.go b/vendor/github.com/google/go-github/v24/github/activity_events.go
new file mode 100644
index 000000000..1754b78e9
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/activity_events.go
@@ -0,0 +1,215 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// ListEvents drinks from the firehose of all public events across GitHub.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events
+func (s *ActivityService) ListEvents(ctx context.Context, opt *ListOptions) ([]*Event, *Response, error) {
+	u, err := addOptions("events", opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var events []*Event
+	resp, err := s.client.Do(ctx, req, &events)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return events, resp, nil
+}
+
+// ListRepositoryEvents lists events for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/#list-repository-events
+func (s *ActivityService) ListRepositoryEvents(ctx context.Context, owner, repo string, opt *ListOptions) ([]*Event, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/events", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var events []*Event
+	resp, err := s.client.Do(ctx, req, &events)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return events, resp, nil
+}
+
+// ListIssueEventsForRepository lists issue events for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/#list-issue-events-for-a-repository
+func (s *ActivityService) ListIssueEventsForRepository(ctx context.Context, owner, repo string, opt *ListOptions) ([]*IssueEvent, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/events", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var events []*IssueEvent
+	resp, err := s.client.Do(ctx, req, &events)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return events, resp, nil
+}
+
+// ListEventsForRepoNetwork lists public events for a network of repositories.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-for-a-network-of-repositories
+func (s *ActivityService) ListEventsForRepoNetwork(ctx context.Context, owner, repo string, opt *ListOptions) ([]*Event, *Response, error) {
+	u := fmt.Sprintf("networks/%v/%v/events", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var events []*Event
+	resp, err := s.client.Do(ctx, req, &events)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return events, resp, nil
+}
+
+// ListEventsForOrganization lists public events for an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-for-an-organization
+func (s *ActivityService) ListEventsForOrganization(ctx context.Context, org string, opt *ListOptions) ([]*Event, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/events", org)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var events []*Event
+	resp, err := s.client.Do(ctx, req, &events)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return events, resp, nil
+}
+
+// ListEventsPerformedByUser lists the events performed by a user. If publicOnly is
+// true, only public events will be returned.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-performed-by-a-user
+func (s *ActivityService) ListEventsPerformedByUser(ctx context.Context, user string, publicOnly bool, opt *ListOptions) ([]*Event, *Response, error) {
+	var u string
+	if publicOnly {
+		u = fmt.Sprintf("users/%v/events/public", user)
+	} else {
+		u = fmt.Sprintf("users/%v/events", user)
+	}
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var events []*Event
+	resp, err := s.client.Do(ctx, req, &events)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return events, resp, nil
+}
+
+// ListEventsReceivedByUser lists the events received by a user. If publicOnly is
+// true, only public events will be returned.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-that-a-user-has-received
+func (s *ActivityService) ListEventsReceivedByUser(ctx context.Context, user string, publicOnly bool, opt *ListOptions) ([]*Event, *Response, error) {
+	var u string
+	if publicOnly {
+		u = fmt.Sprintf("users/%v/received_events/public", user)
+	} else {
+		u = fmt.Sprintf("users/%v/received_events", user)
+	}
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var events []*Event
+	resp, err := s.client.Do(ctx, req, &events)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return events, resp, nil
+}
+
+// ListUserEventsForOrganization provides the user’s organization dashboard. You
+// must be authenticated as the user to view this.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-for-an-organization
+func (s *ActivityService) ListUserEventsForOrganization(ctx context.Context, org, user string, opt *ListOptions) ([]*Event, *Response, error) {
+	u := fmt.Sprintf("users/%v/events/orgs/%v", user, org)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var events []*Event
+	resp, err := s.client.Do(ctx, req, &events)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return events, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/activity_notifications.go b/vendor/github.com/google/go-github/v24/github/activity_notifications.go
new file mode 100644
index 000000000..45c8b2aec
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/activity_notifications.go
@@ -0,0 +1,223 @@
+// Copyright 2014 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// Notification identifies a GitHub notification for a user.
+type Notification struct {
+	ID         *string              `json:"id,omitempty"`
+	Repository *Repository          `json:"repository,omitempty"`
+	Subject    *NotificationSubject `json:"subject,omitempty"`
+
+	// Reason identifies the event that triggered the notification.
+	//
+	// GitHub API docs: https://developer.github.com/v3/activity/notifications/#notification-reasons
+	Reason *string `json:"reason,omitempty"`
+
+	Unread     *bool      `json:"unread,omitempty"`
+	UpdatedAt  *time.Time `json:"updated_at,omitempty"`
+	LastReadAt *time.Time `json:"last_read_at,omitempty"`
+	URL        *string    `json:"url,omitempty"`
+}
+
+// NotificationSubject identifies the subject of a notification.
+type NotificationSubject struct {
+	Title            *string `json:"title,omitempty"`
+	URL              *string `json:"url,omitempty"`
+	LatestCommentURL *string `json:"latest_comment_url,omitempty"`
+	Type             *string `json:"type,omitempty"`
+}
+
+// NotificationListOptions specifies the optional parameters to the
+// ActivityService.ListNotifications method.
+type NotificationListOptions struct {
+	All           bool      `url:"all,omitempty"`
+	Participating bool      `url:"participating,omitempty"`
+	Since         time.Time `url:"since,omitempty"`
+	Before        time.Time `url:"before,omitempty"`
+
+	ListOptions
+}
+
+// ListNotifications lists all notifications for the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/notifications/#list-your-notifications
+func (s *ActivityService) ListNotifications(ctx context.Context, opt *NotificationListOptions) ([]*Notification, *Response, error) {
+	u := fmt.Sprintf("notifications")
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var notifications []*Notification
+	resp, err := s.client.Do(ctx, req, &notifications)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return notifications, resp, nil
+}
+
+// ListRepositoryNotifications lists all notifications in a given repository
+// for the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/notifications/#list-your-notifications-in-a-repository
+func (s *ActivityService) ListRepositoryNotifications(ctx context.Context, owner, repo string, opt *NotificationListOptions) ([]*Notification, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/notifications", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var notifications []*Notification
+	resp, err := s.client.Do(ctx, req, &notifications)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return notifications, resp, nil
+}
+
+type markReadOptions struct {
+	LastReadAt time.Time `json:"last_read_at,omitempty"`
+}
+
+// MarkNotificationsRead marks all notifications up to lastRead as read.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/notifications/#mark-as-read
+func (s *ActivityService) MarkNotificationsRead(ctx context.Context, lastRead time.Time) (*Response, error) {
+	opts := &markReadOptions{
+		LastReadAt: lastRead,
+	}
+	req, err := s.client.NewRequest("PUT", "notifications", opts)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// MarkRepositoryNotificationsRead marks all notifications up to lastRead in
+// the specified repository as read.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/notifications/#mark-notifications-as-read-in-a-repository
+func (s *ActivityService) MarkRepositoryNotificationsRead(ctx context.Context, owner, repo string, lastRead time.Time) (*Response, error) {
+	opts := &markReadOptions{
+		LastReadAt: lastRead,
+	}
+	u := fmt.Sprintf("repos/%v/%v/notifications", owner, repo)
+	req, err := s.client.NewRequest("PUT", u, opts)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// GetThread gets the specified notification thread.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/notifications/#view-a-single-thread
+func (s *ActivityService) GetThread(ctx context.Context, id string) (*Notification, *Response, error) {
+	u := fmt.Sprintf("notifications/threads/%v", id)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	notification := new(Notification)
+	resp, err := s.client.Do(ctx, req, notification)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return notification, resp, nil
+}
+
+// MarkThreadRead marks the specified thread as read.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/notifications/#mark-a-thread-as-read
+func (s *ActivityService) MarkThreadRead(ctx context.Context, id string) (*Response, error) {
+	u := fmt.Sprintf("notifications/threads/%v", id)
+
+	req, err := s.client.NewRequest("PATCH", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// GetThreadSubscription checks to see if the authenticated user is subscribed
+// to a thread.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/notifications/#get-a-thread-subscription
+func (s *ActivityService) GetThreadSubscription(ctx context.Context, id string) (*Subscription, *Response, error) {
+	u := fmt.Sprintf("notifications/threads/%v/subscription", id)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	sub := new(Subscription)
+	resp, err := s.client.Do(ctx, req, sub)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return sub, resp, nil
+}
+
+// SetThreadSubscription sets the subscription for the specified thread for the
+// authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/notifications/#set-a-thread-subscription
+func (s *ActivityService) SetThreadSubscription(ctx context.Context, id string, subscription *Subscription) (*Subscription, *Response, error) {
+	u := fmt.Sprintf("notifications/threads/%v/subscription", id)
+
+	req, err := s.client.NewRequest("PUT", u, subscription)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	sub := new(Subscription)
+	resp, err := s.client.Do(ctx, req, sub)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return sub, resp, nil
+}
+
+// DeleteThreadSubscription deletes the subscription for the specified thread
+// for the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/notifications/#delete-a-thread-subscription
+func (s *ActivityService) DeleteThreadSubscription(ctx context.Context, id string) (*Response, error) {
+	u := fmt.Sprintf("notifications/threads/%v/subscription", id)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/activity_star.go b/vendor/github.com/google/go-github/v24/github/activity_star.go
new file mode 100644
index 000000000..5ae5c1016
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/activity_star.go
@@ -0,0 +1,137 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"strings"
+)
+
+// StarredRepository is returned by ListStarred.
+type StarredRepository struct {
+	StarredAt  *Timestamp  `json:"starred_at,omitempty"`
+	Repository *Repository `json:"repo,omitempty"`
+}
+
+// Stargazer represents a user that has starred a repository.
+type Stargazer struct {
+	StarredAt *Timestamp `json:"starred_at,omitempty"`
+	User      *User      `json:"user,omitempty"`
+}
+
+// ListStargazers lists people who have starred the specified repo.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/starring/#list-stargazers
+func (s *ActivityService) ListStargazers(ctx context.Context, owner, repo string, opt *ListOptions) ([]*Stargazer, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/stargazers", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeStarringPreview)
+
+	var stargazers []*Stargazer
+	resp, err := s.client.Do(ctx, req, &stargazers)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return stargazers, resp, nil
+}
+
+// ActivityListStarredOptions specifies the optional parameters to the
+// ActivityService.ListStarred method.
+type ActivityListStarredOptions struct {
+	// How to sort the repository list. Possible values are: created, updated,
+	// pushed, full_name. Default is "full_name".
+	Sort string `url:"sort,omitempty"`
+
+	// Direction in which to sort repositories. Possible values are: asc, desc.
+	// Default is "asc" when sort is "full_name", otherwise default is "desc".
+	Direction string `url:"direction,omitempty"`
+
+	ListOptions
+}
+
+// ListStarred lists all the repos starred by a user. Passing the empty string
+// will list the starred repositories for the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/starring/#list-repositories-being-starred
+func (s *ActivityService) ListStarred(ctx context.Context, user string, opt *ActivityListStarredOptions) ([]*StarredRepository, *Response, error) {
+	var u string
+	if user != "" {
+		u = fmt.Sprintf("users/%v/starred", user)
+	} else {
+		u = "user/starred"
+	}
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when APIs fully launch
+	acceptHeaders := []string{mediaTypeStarringPreview, mediaTypeTopicsPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	var repos []*StarredRepository
+	resp, err := s.client.Do(ctx, req, &repos)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return repos, resp, nil
+}
+
+// IsStarred checks if a repository is starred by authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/starring/#check-if-you-are-starring-a-repository
+func (s *ActivityService) IsStarred(ctx context.Context, owner, repo string) (bool, *Response, error) {
+	u := fmt.Sprintf("user/starred/%v/%v", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return false, nil, err
+	}
+	resp, err := s.client.Do(ctx, req, nil)
+	starred, err := parseBoolResponse(err)
+	return starred, resp, err
+}
+
+// Star a repository as the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/starring/#star-a-repository
+func (s *ActivityService) Star(ctx context.Context, owner, repo string) (*Response, error) {
+	u := fmt.Sprintf("user/starred/%v/%v", owner, repo)
+	req, err := s.client.NewRequest("PUT", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
+
+// Unstar a repository as the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/starring/#unstar-a-repository
+func (s *ActivityService) Unstar(ctx context.Context, owner, repo string) (*Response, error) {
+	u := fmt.Sprintf("user/starred/%v/%v", owner, repo)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/activity_watching.go b/vendor/github.com/google/go-github/v24/github/activity_watching.go
new file mode 100644
index 000000000..c749ca86e
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/activity_watching.go
@@ -0,0 +1,146 @@
+// Copyright 2014 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// Subscription identifies a repository or thread subscription.
+type Subscription struct {
+	Subscribed *bool      `json:"subscribed,omitempty"`
+	Ignored    *bool      `json:"ignored,omitempty"`
+	Reason     *string    `json:"reason,omitempty"`
+	CreatedAt  *Timestamp `json:"created_at,omitempty"`
+	URL        *string    `json:"url,omitempty"`
+
+	// only populated for repository subscriptions
+	RepositoryURL *string `json:"repository_url,omitempty"`
+
+	// only populated for thread subscriptions
+	ThreadURL *string `json:"thread_url,omitempty"`
+}
+
+// ListWatchers lists watchers of a particular repo.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/watching/#list-watchers
+func (s *ActivityService) ListWatchers(ctx context.Context, owner, repo string, opt *ListOptions) ([]*User, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/subscribers", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var watchers []*User
+	resp, err := s.client.Do(ctx, req, &watchers)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return watchers, resp, nil
+}
+
+// ListWatched lists the repositories the specified user is watching. Passing
+// the empty string will fetch watched repos for the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/watching/#list-repositories-being-watched
+func (s *ActivityService) ListWatched(ctx context.Context, user string, opt *ListOptions) ([]*Repository, *Response, error) {
+	var u string
+	if user != "" {
+		u = fmt.Sprintf("users/%v/subscriptions", user)
+	} else {
+		u = "user/subscriptions"
+	}
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var watched []*Repository
+	resp, err := s.client.Do(ctx, req, &watched)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return watched, resp, nil
+}
+
+// GetRepositorySubscription returns the subscription for the specified
+// repository for the authenticated user. If the authenticated user is not
+// watching the repository, a nil Subscription is returned.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/watching/#get-a-repository-subscription
+func (s *ActivityService) GetRepositorySubscription(ctx context.Context, owner, repo string) (*Subscription, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/subscription", owner, repo)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	sub := new(Subscription)
+	resp, err := s.client.Do(ctx, req, sub)
+	if err != nil {
+		// if it's just a 404, don't return that as an error
+		_, err = parseBoolResponse(err)
+		return nil, resp, err
+	}
+
+	return sub, resp, nil
+}
+
+// SetRepositorySubscription sets the subscription for the specified repository
+// for the authenticated user.
+//
+// To watch a repository, set subscription.Subscribed to true.
+// To ignore notifications made within a repository, set subscription.Ignored to true.
+// To stop watching a repository, use DeleteRepositorySubscription.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/watching/#set-a-repository-subscription
+func (s *ActivityService) SetRepositorySubscription(ctx context.Context, owner, repo string, subscription *Subscription) (*Subscription, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/subscription", owner, repo)
+
+	req, err := s.client.NewRequest("PUT", u, subscription)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	sub := new(Subscription)
+	resp, err := s.client.Do(ctx, req, sub)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return sub, resp, nil
+}
+
+// DeleteRepositorySubscription deletes the subscription for the specified
+// repository for the authenticated user.
+//
+// This is used to stop watching a repository. To control whether or not to
+// receive notifications from a repository, use SetRepositorySubscription.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/watching/#delete-a-repository-subscription
+func (s *ActivityService) DeleteRepositorySubscription(ctx context.Context, owner, repo string) (*Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/subscription", owner, repo)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/admin.go b/vendor/github.com/google/go-github/v24/github/admin.go
new file mode 100644
index 000000000..2d96733a1
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/admin.go
@@ -0,0 +1,101 @@
+// Copyright 2016 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// AdminService handles communication with the admin related methods of the
+// GitHub API. These API routes are normally only accessible for GitHub
+// Enterprise installations.
+//
+// GitHub API docs: https://developer.github.com/v3/enterprise/
+type AdminService service
+
+// TeamLDAPMapping represents the mapping between a GitHub team and an LDAP group.
+type TeamLDAPMapping struct {
+	ID          *int64  `json:"id,omitempty"`
+	LDAPDN      *string `json:"ldap_dn,omitempty"`
+	URL         *string `json:"url,omitempty"`
+	Name        *string `json:"name,omitempty"`
+	Slug        *string `json:"slug,omitempty"`
+	Description *string `json:"description,omitempty"`
+	Privacy     *string `json:"privacy,omitempty"`
+	Permission  *string `json:"permission,omitempty"`
+
+	MembersURL      *string `json:"members_url,omitempty"`
+	RepositoriesURL *string `json:"repositories_url,omitempty"`
+}
+
+func (m TeamLDAPMapping) String() string {
+	return Stringify(m)
+}
+
+// UserLDAPMapping represents the mapping between a GitHub user and an LDAP user.
+type UserLDAPMapping struct {
+	ID         *int64  `json:"id,omitempty"`
+	LDAPDN     *string `json:"ldap_dn,omitempty"`
+	Login      *string `json:"login,omitempty"`
+	AvatarURL  *string `json:"avatar_url,omitempty"`
+	GravatarID *string `json:"gravatar_id,omitempty"`
+	Type       *string `json:"type,omitempty"`
+	SiteAdmin  *bool   `json:"site_admin,omitempty"`
+
+	URL               *string `json:"url,omitempty"`
+	EventsURL         *string `json:"events_url,omitempty"`
+	FollowingURL      *string `json:"following_url,omitempty"`
+	FollowersURL      *string `json:"followers_url,omitempty"`
+	GistsURL          *string `json:"gists_url,omitempty"`
+	OrganizationsURL  *string `json:"organizations_url,omitempty"`
+	ReceivedEventsURL *string `json:"received_events_url,omitempty"`
+	ReposURL          *string `json:"repos_url,omitempty"`
+	StarredURL        *string `json:"starred_url,omitempty"`
+	SubscriptionsURL  *string `json:"subscriptions_url,omitempty"`
+}
+
+func (m UserLDAPMapping) String() string {
+	return Stringify(m)
+}
+
+// UpdateUserLDAPMapping updates the mapping between a GitHub user and an LDAP user.
+//
+// GitHub API docs: https://developer.github.com/v3/enterprise/ldap/#update-ldap-mapping-for-a-user
+func (s *AdminService) UpdateUserLDAPMapping(ctx context.Context, user string, mapping *UserLDAPMapping) (*UserLDAPMapping, *Response, error) {
+	u := fmt.Sprintf("admin/ldap/users/%v/mapping", user)
+	req, err := s.client.NewRequest("PATCH", u, mapping)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	m := new(UserLDAPMapping)
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// UpdateTeamLDAPMapping updates the mapping between a GitHub team and an LDAP group.
+//
+// GitHub API docs: https://developer.github.com/v3/enterprise/ldap/#update-ldap-mapping-for-a-team
+func (s *AdminService) UpdateTeamLDAPMapping(ctx context.Context, team int64, mapping *TeamLDAPMapping) (*TeamLDAPMapping, *Response, error) {
+	u := fmt.Sprintf("admin/ldap/teams/%v/mapping", team)
+	req, err := s.client.NewRequest("PATCH", u, mapping)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	m := new(TeamLDAPMapping)
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/admin_stats.go b/vendor/github.com/google/go-github/v24/github/admin_stats.go
new file mode 100644
index 000000000..b5645f8c1
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/admin_stats.go
@@ -0,0 +1,171 @@
+// Copyright 2017 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// AdminStats represents a variety of stats of a Github Enterprise
+// installation.
+type AdminStats struct {
+	Issues     *IssueStats     `json:"issues,omitempty"`
+	Hooks      *HookStats      `json:"hooks,omitempty"`
+	Milestones *MilestoneStats `json:"milestones,omitempty"`
+	Orgs       *OrgStats       `json:"orgs,omitempty"`
+	Comments   *CommentStats   `json:"comments,omitempty"`
+	Pages      *PageStats      `json:"pages,omitempty"`
+	Users      *UserStats      `json:"users,omitempty"`
+	Gists      *GistStats      `json:"gists,omitempty"`
+	Pulls      *PullStats      `json:"pulls,omitempty"`
+	Repos      *RepoStats      `json:"repos,omitempty"`
+}
+
+func (s AdminStats) String() string {
+	return Stringify(s)
+}
+
+// IssueStats represents the number of total, open and closed issues.
+type IssueStats struct {
+	TotalIssues  *int `json:"total_issues,omitempty"`
+	OpenIssues   *int `json:"open_issues,omitempty"`
+	ClosedIssues *int `json:"closed_issues,omitempty"`
+}
+
+func (s IssueStats) String() string {
+	return Stringify(s)
+}
+
+// HookStats represents the number of total, active and inactive hooks.
+type HookStats struct {
+	TotalHooks    *int `json:"total_hooks,omitempty"`
+	ActiveHooks   *int `json:"active_hooks,omitempty"`
+	InactiveHooks *int `json:"inactive_hooks,omitempty"`
+}
+
+func (s HookStats) String() string {
+	return Stringify(s)
+}
+
+// MilestoneStats represents the number of total, open and close milestones.
+type MilestoneStats struct {
+	TotalMilestones  *int `json:"total_milestones,omitempty"`
+	OpenMilestones   *int `json:"open_milestones,omitempty"`
+	ClosedMilestones *int `json:"closed_milestones,omitempty"`
+}
+
+func (s MilestoneStats) String() string {
+	return Stringify(s)
+}
+
+// OrgStats represents the number of total, disabled organizations and the team
+// and team member count.
+type OrgStats struct {
+	TotalOrgs        *int `json:"total_orgs,omitempty"`
+	DisabledOrgs     *int `json:"disabled_orgs,omitempty"`
+	TotalTeams       *int `json:"total_teams,omitempty"`
+	TotalTeamMembers *int `json:"total_team_members,omitempty"`
+}
+
+func (s OrgStats) String() string {
+	return Stringify(s)
+}
+
+// CommentStats represents the number of total comments on commits, gists, issues
+// and pull requests.
+type CommentStats struct {
+	TotalCommitComments      *int `json:"total_commit_comments,omitempty"`
+	TotalGistComments        *int `json:"total_gist_comments,omitempty"`
+	TotalIssueComments       *int `json:"total_issue_comments,omitempty"`
+	TotalPullRequestComments *int `json:"total_pull_request_comments,omitempty"`
+}
+
+func (s CommentStats) String() string {
+	return Stringify(s)
+}
+
+// PageStats represents the total number of github pages.
+type PageStats struct {
+	TotalPages *int `json:"total_pages,omitempty"`
+}
+
+func (s PageStats) String() string {
+	return Stringify(s)
+}
+
+// UserStats represents the number of total, admin and suspended users.
+type UserStats struct {
+	TotalUsers     *int `json:"total_users,omitempty"`
+	AdminUsers     *int `json:"admin_users,omitempty"`
+	SuspendedUsers *int `json:"suspended_users,omitempty"`
+}
+
+func (s UserStats) String() string {
+	return Stringify(s)
+}
+
+// GistStats represents the number of total, private and public gists.
+type GistStats struct {
+	TotalGists   *int `json:"total_gists,omitempty"`
+	PrivateGists *int `json:"private_gists,omitempty"`
+	PublicGists  *int `json:"public_gists,omitempty"`
+}
+
+func (s GistStats) String() string {
+	return Stringify(s)
+}
+
+// PullStats represents the number of total, merged, mergable and unmergeable
+// pull-requests.
+type PullStats struct {
+	TotalPulls      *int `json:"total_pulls,omitempty"`
+	MergedPulls     *int `json:"merged_pulls,omitempty"`
+	MergablePulls   *int `json:"mergeable_pulls,omitempty"`
+	UnmergablePulls *int `json:"unmergeable_pulls,omitempty"`
+}
+
+func (s PullStats) String() string {
+	return Stringify(s)
+}
+
+// RepoStats represents the number of total, root, fork, organization repositories
+// together with the total number of pushes and wikis.
+type RepoStats struct {
+	TotalRepos  *int `json:"total_repos,omitempty"`
+	RootRepos   *int `json:"root_repos,omitempty"`
+	ForkRepos   *int `json:"fork_repos,omitempty"`
+	OrgRepos    *int `json:"org_repos,omitempty"`
+	TotalPushes *int `json:"total_pushes,omitempty"`
+	TotalWikis  *int `json:"total_wikis,omitempty"`
+}
+
+func (s RepoStats) String() string {
+	return Stringify(s)
+}
+
+// GetAdminStats returns a variety of metrics about a Github Enterprise
+// installation.
+//
+// Please note that this is only available to site administrators,
+// otherwise it will error with a 404 not found (instead of 401 or 403).
+//
+// GitHub API docs: https://developer.github.com/v3/enterprise-admin/admin_stats/
+func (s *AdminService) GetAdminStats(ctx context.Context) (*AdminStats, *Response, error) {
+	u := fmt.Sprintf("enterprise/stats/all")
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	m := new(AdminStats)
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/apps.go b/vendor/github.com/google/go-github/v24/github/apps.go
new file mode 100644
index 000000000..ae3aabda3
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/apps.go
@@ -0,0 +1,230 @@
+// Copyright 2016 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// AppsService provides access to the installation related functions
+// in the GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/
+type AppsService service
+
+// App represents a GitHub App.
+type App struct {
+	ID          *int64     `json:"id,omitempty"`
+	NodeID      *string    `json:"node_id,omitempty"`
+	Owner       *User      `json:"owner,omitempty"`
+	Name        *string    `json:"name,omitempty"`
+	Description *string    `json:"description,omitempty"`
+	ExternalURL *string    `json:"external_url,omitempty"`
+	HTMLURL     *string    `json:"html_url,omitempty"`
+	CreatedAt   *time.Time `json:"created_at,omitempty"`
+	UpdatedAt   *time.Time `json:"updated_at,omitempty"`
+}
+
+// InstallationToken represents an installation token.
+type InstallationToken struct {
+	Token     *string    `json:"token,omitempty"`
+	ExpiresAt *time.Time `json:"expires_at,omitempty"`
+}
+
+// InstallationPermissions lists the permissions for metadata, contents, issues and single file for an installation.
+type InstallationPermissions struct {
+	Metadata   *string `json:"metadata,omitempty"`
+	Contents   *string `json:"contents,omitempty"`
+	Issues     *string `json:"issues,omitempty"`
+	SingleFile *string `json:"single_file,omitempty"`
+}
+
+// Installation represents a GitHub Apps installation.
+type Installation struct {
+	ID                  *int64                   `json:"id,omitempty"`
+	AppID               *int64                   `json:"app_id,omitempty"`
+	TargetID            *int64                   `json:"target_id,omitempty"`
+	Account             *User                    `json:"account,omitempty"`
+	AccessTokensURL     *string                  `json:"access_tokens_url,omitempty"`
+	RepositoriesURL     *string                  `json:"repositories_url,omitempty"`
+	HTMLURL             *string                  `json:"html_url,omitempty"`
+	TargetType          *string                  `json:"target_type,omitempty"`
+	SingleFileName      *string                  `json:"single_file_name,omitempty"`
+	RepositorySelection *string                  `json:"repository_selection,omitempty"`
+	Events              []string                 `json:"events,omitempty"`
+	Permissions         *InstallationPermissions `json:"permissions,omitempty"`
+	CreatedAt           *Timestamp               `json:"created_at,omitempty"`
+	UpdatedAt           *Timestamp               `json:"updated_at,omitempty"`
+}
+
+func (i Installation) String() string {
+	return Stringify(i)
+}
+
+// Get a single GitHub App. Passing the empty string will get
+// the authenticated GitHub App.
+//
+// Note: appSlug is just the URL-friendly name of your GitHub App.
+// You can find this on the settings page for your GitHub App
+// (e.g., https://github.com/settings/apps/:app_slug).
+//
+// GitHub API docs: https://developer.github.com/v3/apps/#get-a-single-github-app
+func (s *AppsService) Get(ctx context.Context, appSlug string) (*App, *Response, error) {
+	var u string
+	if appSlug != "" {
+		u = fmt.Sprintf("apps/%v", appSlug)
+	} else {
+		u = "app"
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeIntegrationPreview)
+
+	app := new(App)
+	resp, err := s.client.Do(ctx, req, app)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return app, resp, nil
+}
+
+// ListInstallations lists the installations that the current GitHub App has.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/#find-installations
+func (s *AppsService) ListInstallations(ctx context.Context, opt *ListOptions) ([]*Installation, *Response, error) {
+	u, err := addOptions("app/installations", opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeIntegrationPreview)
+
+	var i []*Installation
+	resp, err := s.client.Do(ctx, req, &i)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return i, resp, nil
+}
+
+// GetInstallation returns the specified installation.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/#get-a-single-installation
+func (s *AppsService) GetInstallation(ctx context.Context, id int64) (*Installation, *Response, error) {
+	return s.getInstallation(ctx, fmt.Sprintf("app/installations/%v", id))
+}
+
+// ListUserInstallations lists installations that are accessible to the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/#list-installations-for-user
+func (s *AppsService) ListUserInstallations(ctx context.Context, opt *ListOptions) ([]*Installation, *Response, error) {
+	u, err := addOptions("user/installations", opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeIntegrationPreview)
+
+	var i struct {
+		Installations []*Installation `json:"installations"`
+	}
+	resp, err := s.client.Do(ctx, req, &i)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return i.Installations, resp, nil
+}
+
+// CreateInstallationToken creates a new installation token.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/#create-a-new-installation-token
+func (s *AppsService) CreateInstallationToken(ctx context.Context, id int64) (*InstallationToken, *Response, error) {
+	u := fmt.Sprintf("app/installations/%v/access_tokens", id)
+
+	req, err := s.client.NewRequest("POST", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeIntegrationPreview)
+
+	t := new(InstallationToken)
+	resp, err := s.client.Do(ctx, req, t)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return t, resp, nil
+}
+
+// FindOrganizationInstallation finds the organization's installation information.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/#find-organization-installation
+func (s *AppsService) FindOrganizationInstallation(ctx context.Context, org string) (*Installation, *Response, error) {
+	return s.getInstallation(ctx, fmt.Sprintf("orgs/%v/installation", org))
+}
+
+// FindRepositoryInstallation finds the repository's installation information.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/#find-repository-installation
+func (s *AppsService) FindRepositoryInstallation(ctx context.Context, owner, repo string) (*Installation, *Response, error) {
+	return s.getInstallation(ctx, fmt.Sprintf("repos/%v/%v/installation", owner, repo))
+}
+
+// FindRepositoryInstallationByID finds the repository's installation information.
+//
+// Note: FindRepositoryInstallationByID uses the undocumented GitHub API endpoint /repositories/:id/installation.
+func (s *AppsService) FindRepositoryInstallationByID(ctx context.Context, id int64) (*Installation, *Response, error) {
+	return s.getInstallation(ctx, fmt.Sprintf("repositories/%d/installation", id))
+}
+
+// FindUserInstallation finds the user's installation information.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/#find-repository-installation
+func (s *AppsService) FindUserInstallation(ctx context.Context, user string) (*Installation, *Response, error) {
+	return s.getInstallation(ctx, fmt.Sprintf("users/%v/installation", user))
+}
+
+func (s *AppsService) getInstallation(ctx context.Context, url string) (*Installation, *Response, error) {
+	req, err := s.client.NewRequest("GET", url, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeIntegrationPreview)
+
+	i := new(Installation)
+	resp, err := s.client.Do(ctx, req, i)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return i, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/apps_installation.go b/vendor/github.com/google/go-github/v24/github/apps_installation.go
new file mode 100644
index 000000000..09d4043fe
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/apps_installation.go
@@ -0,0 +1,103 @@
+// Copyright 2016 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// ListRepos lists the repositories that are accessible to the authenticated installation.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/installations/#list-repositories
+func (s *AppsService) ListRepos(ctx context.Context, opt *ListOptions) ([]*Repository, *Response, error) {
+	u, err := addOptions("installation/repositories", opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeIntegrationPreview)
+
+	var r struct {
+		Repositories []*Repository `json:"repositories"`
+	}
+	resp, err := s.client.Do(ctx, req, &r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r.Repositories, resp, nil
+}
+
+// ListUserRepos lists repositories that are accessible
+// to the authenticated user for an installation.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/installations/#list-repositories-accessible-to-the-user-for-an-installation
+func (s *AppsService) ListUserRepos(ctx context.Context, id int64, opt *ListOptions) ([]*Repository, *Response, error) {
+	u := fmt.Sprintf("user/installations/%v/repositories", id)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeIntegrationPreview)
+
+	var r struct {
+		Repositories []*Repository `json:"repositories"`
+	}
+	resp, err := s.client.Do(ctx, req, &r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r.Repositories, resp, nil
+}
+
+// AddRepository adds a single repository to an installation.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/installations/#add-repository-to-installation
+func (s *AppsService) AddRepository(ctx context.Context, instID, repoID int64) (*Repository, *Response, error) {
+	u := fmt.Sprintf("user/installations/%v/repositories/%v", instID, repoID)
+	req, err := s.client.NewRequest("PUT", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+	req.Header.Set("Accept", mediaTypeIntegrationPreview)
+
+	r := new(Repository)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
+
+// RemoveRepository removes a single repository from an installation.
+//
+// GitHub docs: https://developer.github.com/v3/apps/installations/#remove-repository-from-installation
+func (s *AppsService) RemoveRepository(ctx context.Context, instID, repoID int64) (*Response, error) {
+	u := fmt.Sprintf("user/installations/%v/repositories/%v", instID, repoID)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	req.Header.Set("Accept", mediaTypeIntegrationPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/apps_marketplace.go b/vendor/github.com/google/go-github/v24/github/apps_marketplace.go
new file mode 100644
index 000000000..6dd568a2d
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/apps_marketplace.go
@@ -0,0 +1,183 @@
+// Copyright 2017 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// MarketplaceService handles communication with the marketplace related
+// methods of the GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/marketplace/
+type MarketplaceService struct {
+	client *Client
+	// Stubbed controls whether endpoints that return stubbed data are used
+	// instead of production endpoints. Stubbed data is fake data that's useful
+	// for testing your GitHub Apps. Stubbed data is hard-coded and will not
+	// change based on actual subscriptions.
+	//
+	// GitHub API docs: https://developer.github.com/v3/apps/marketplace/
+	Stubbed bool
+}
+
+// MarketplacePlan represents a GitHub Apps Marketplace Listing Plan.
+type MarketplacePlan struct {
+	URL                 *string `json:"url,omitempty"`
+	AccountsURL         *string `json:"accounts_url,omitempty"`
+	ID                  *int64  `json:"id,omitempty"`
+	Name                *string `json:"name,omitempty"`
+	Description         *string `json:"description,omitempty"`
+	MonthlyPriceInCents *int    `json:"monthly_price_in_cents,omitempty"`
+	YearlyPriceInCents  *int    `json:"yearly_price_in_cents,omitempty"`
+	// The pricing model for this listing.  Can be one of "flat-rate", "per-unit", or "free".
+	PriceModel *string   `json:"price_model,omitempty"`
+	UnitName   *string   `json:"unit_name,omitempty"`
+	Bullets    *[]string `json:"bullets,omitempty"`
+	// State can be one of the values "draft" or "published".
+	State        *string `json:"state,omitempty"`
+	HasFreeTrial *bool   `json:"has_free_trial,omitempty"`
+}
+
+// MarketplacePurchase represents a GitHub Apps Marketplace Purchase.
+type MarketplacePurchase struct {
+	// BillingCycle can be one of the values "yearly", "monthly" or nil.
+	BillingCycle    *string                 `json:"billing_cycle,omitempty"`
+	NextBillingDate *Timestamp              `json:"next_billing_date,omitempty"`
+	UnitCount       *int                    `json:"unit_count,omitempty"`
+	Plan            *MarketplacePlan        `json:"plan,omitempty"`
+	Account         *MarketplacePlanAccount `json:"account,omitempty"`
+	OnFreeTrial     *bool                   `json:"on_free_trial,omitempty"`
+	FreeTrialEndsOn *Timestamp              `json:"free_trial_ends_on,omitempty"`
+}
+
+// MarketplacePendingChange represents a pending change to a GitHub Apps Marketplace Plan.
+type MarketplacePendingChange struct {
+	EffectiveDate *Timestamp       `json:"effective_date,omitempty"`
+	UnitCount     *int             `json:"unit_count,omitempty"`
+	ID            *int64           `json:"id,omitempty"`
+	Plan          *MarketplacePlan `json:"plan,omitempty"`
+}
+
+// MarketplacePlanAccount represents a GitHub Account (user or organization) on a specific plan.
+type MarketplacePlanAccount struct {
+	URL                      *string                   `json:"url,omitempty"`
+	Type                     *string                   `json:"type,omitempty"`
+	ID                       *int64                    `json:"id,omitempty"`
+	Login                    *string                   `json:"login,omitempty"`
+	Email                    *string                   `json:"email,omitempty"`
+	OrganizationBillingEmail *string                   `json:"organization_billing_email,omitempty"`
+	MarketplacePurchase      *MarketplacePurchase      `json:"marketplace_purchase,omitempty"`
+	MarketplacePendingChange *MarketplacePendingChange `json:"marketplace_pending_change,omitempty"`
+}
+
+// ListPlans lists all plans for your Marketplace listing.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/marketplace/#list-all-plans-for-your-marketplace-listing
+func (s *MarketplaceService) ListPlans(ctx context.Context, opt *ListOptions) ([]*MarketplacePlan, *Response, error) {
+	uri := s.marketplaceURI("plans")
+	u, err := addOptions(uri, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var plans []*MarketplacePlan
+	resp, err := s.client.Do(ctx, req, &plans)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return plans, resp, nil
+}
+
+// ListPlanAccountsForPlan lists all GitHub accounts (user or organization) on a specific plan.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/marketplace/#list-all-github-accounts-user-or-organization-on-a-specific-plan
+func (s *MarketplaceService) ListPlanAccountsForPlan(ctx context.Context, planID int64, opt *ListOptions) ([]*MarketplacePlanAccount, *Response, error) {
+	uri := s.marketplaceURI(fmt.Sprintf("plans/%v/accounts", planID))
+	u, err := addOptions(uri, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var accounts []*MarketplacePlanAccount
+	resp, err := s.client.Do(ctx, req, &accounts)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return accounts, resp, nil
+}
+
+// ListPlanAccountsForAccount lists all GitHub accounts (user or organization) associated with an account.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/marketplace/#check-if-a-github-account-is-associated-with-any-marketplace-listing
+func (s *MarketplaceService) ListPlanAccountsForAccount(ctx context.Context, accountID int64, opt *ListOptions) ([]*MarketplacePlanAccount, *Response, error) {
+	uri := s.marketplaceURI(fmt.Sprintf("accounts/%v", accountID))
+	u, err := addOptions(uri, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var accounts []*MarketplacePlanAccount
+	resp, err := s.client.Do(ctx, req, &accounts)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return accounts, resp, nil
+}
+
+// ListMarketplacePurchasesForUser lists all GitHub marketplace purchases made by a user.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/marketplace/#get-a-users-marketplace-purchases
+func (s *MarketplaceService) ListMarketplacePurchasesForUser(ctx context.Context, opt *ListOptions) ([]*MarketplacePurchase, *Response, error) {
+	uri := "user/marketplace_purchases"
+	if s.Stubbed {
+		uri = "user/marketplace_purchases/stubbed"
+	}
+
+	u, err := addOptions(uri, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var purchases []*MarketplacePurchase
+	resp, err := s.client.Do(ctx, req, &purchases)
+	if err != nil {
+		return nil, resp, err
+	}
+	return purchases, resp, nil
+}
+
+func (s *MarketplaceService) marketplaceURI(endpoint string) string {
+	url := "marketplace_listing"
+	if s.Stubbed {
+		url = "marketplace_listing/stubbed"
+	}
+	return url + "/" + endpoint
+}
diff --git a/vendor/github.com/google/go-github/v24/github/authorizations.go b/vendor/github.com/google/go-github/v24/github/authorizations.go
new file mode 100644
index 000000000..8ad14328e
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/authorizations.go
@@ -0,0 +1,435 @@
+// Copyright 2015 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// Scope models a GitHub authorization scope.
+//
+// GitHub API docs: https://developer.github.com/v3/oauth/#scopes
+type Scope string
+
+// This is the set of scopes for GitHub API V3
+const (
+	ScopeNone           Scope = "(no scope)" // REVISIT: is this actually returned, or just a documentation artifact?
+	ScopeUser           Scope = "user"
+	ScopeUserEmail      Scope = "user:email"
+	ScopeUserFollow     Scope = "user:follow"
+	ScopePublicRepo     Scope = "public_repo"
+	ScopeRepo           Scope = "repo"
+	ScopeRepoDeployment Scope = "repo_deployment"
+	ScopeRepoStatus     Scope = "repo:status"
+	ScopeDeleteRepo     Scope = "delete_repo"
+	ScopeNotifications  Scope = "notifications"
+	ScopeGist           Scope = "gist"
+	ScopeReadRepoHook   Scope = "read:repo_hook"
+	ScopeWriteRepoHook  Scope = "write:repo_hook"
+	ScopeAdminRepoHook  Scope = "admin:repo_hook"
+	ScopeAdminOrgHook   Scope = "admin:org_hook"
+	ScopeReadOrg        Scope = "read:org"
+	ScopeWriteOrg       Scope = "write:org"
+	ScopeAdminOrg       Scope = "admin:org"
+	ScopeReadPublicKey  Scope = "read:public_key"
+	ScopeWritePublicKey Scope = "write:public_key"
+	ScopeAdminPublicKey Scope = "admin:public_key"
+	ScopeReadGPGKey     Scope = "read:gpg_key"
+	ScopeWriteGPGKey    Scope = "write:gpg_key"
+	ScopeAdminGPGKey    Scope = "admin:gpg_key"
+)
+
+// AuthorizationsService handles communication with the authorization related
+// methods of the GitHub API.
+//
+// This service requires HTTP Basic Authentication; it cannot be accessed using
+// an OAuth token.
+//
+// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/
+type AuthorizationsService service
+
+// Authorization represents an individual GitHub authorization.
+type Authorization struct {
+	ID             *int64            `json:"id,omitempty"`
+	URL            *string           `json:"url,omitempty"`
+	Scopes         []Scope           `json:"scopes,omitempty"`
+	Token          *string           `json:"token,omitempty"`
+	TokenLastEight *string           `json:"token_last_eight,omitempty"`
+	HashedToken    *string           `json:"hashed_token,omitempty"`
+	App            *AuthorizationApp `json:"app,omitempty"`
+	Note           *string           `json:"note,omitempty"`
+	NoteURL        *string           `json:"note_url,omitempty"`
+	UpdatedAt      *Timestamp        `json:"updated_at,omitempty"`
+	CreatedAt      *Timestamp        `json:"created_at,omitempty"`
+	Fingerprint    *string           `json:"fingerprint,omitempty"`
+
+	// User is only populated by the Check and Reset methods.
+	User *User `json:"user,omitempty"`
+}
+
+func (a Authorization) String() string {
+	return Stringify(a)
+}
+
+// AuthorizationApp represents an individual GitHub app (in the context of authorization).
+type AuthorizationApp struct {
+	URL      *string `json:"url,omitempty"`
+	Name     *string `json:"name,omitempty"`
+	ClientID *string `json:"client_id,omitempty"`
+}
+
+func (a AuthorizationApp) String() string {
+	return Stringify(a)
+}
+
+// Grant represents an OAuth application that has been granted access to an account.
+type Grant struct {
+	ID        *int64            `json:"id,omitempty"`
+	URL       *string           `json:"url,omitempty"`
+	App       *AuthorizationApp `json:"app,omitempty"`
+	CreatedAt *Timestamp        `json:"created_at,omitempty"`
+	UpdatedAt *Timestamp        `json:"updated_at,omitempty"`
+	Scopes    []string          `json:"scopes,omitempty"`
+}
+
+func (g Grant) String() string {
+	return Stringify(g)
+}
+
+// AuthorizationRequest represents a request to create an authorization.
+type AuthorizationRequest struct {
+	Scopes       []Scope `json:"scopes,omitempty"`
+	Note         *string `json:"note,omitempty"`
+	NoteURL      *string `json:"note_url,omitempty"`
+	ClientID     *string `json:"client_id,omitempty"`
+	ClientSecret *string `json:"client_secret,omitempty"`
+	Fingerprint  *string `json:"fingerprint,omitempty"`
+}
+
+func (a AuthorizationRequest) String() string {
+	return Stringify(a)
+}
+
+// AuthorizationUpdateRequest represents a request to update an authorization.
+//
+// Note that for any one update, you must only provide one of the "scopes"
+// fields. That is, you may provide only one of "Scopes", or "AddScopes", or
+// "RemoveScopes".
+//
+// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#update-an-existing-authorization
+type AuthorizationUpdateRequest struct {
+	Scopes       []string `json:"scopes,omitempty"`
+	AddScopes    []string `json:"add_scopes,omitempty"`
+	RemoveScopes []string `json:"remove_scopes,omitempty"`
+	Note         *string  `json:"note,omitempty"`
+	NoteURL      *string  `json:"note_url,omitempty"`
+	Fingerprint  *string  `json:"fingerprint,omitempty"`
+}
+
+func (a AuthorizationUpdateRequest) String() string {
+	return Stringify(a)
+}
+
+// List the authorizations for the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#list-your-authorizations
+func (s *AuthorizationsService) List(ctx context.Context, opt *ListOptions) ([]*Authorization, *Response, error) {
+	u := "authorizations"
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var auths []*Authorization
+	resp, err := s.client.Do(ctx, req, &auths)
+	if err != nil {
+		return nil, resp, err
+	}
+	return auths, resp, nil
+}
+
+// Get a single authorization.
+//
+// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#get-a-single-authorization
+func (s *AuthorizationsService) Get(ctx context.Context, id int64) (*Authorization, *Response, error) {
+	u := fmt.Sprintf("authorizations/%d", id)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	a := new(Authorization)
+	resp, err := s.client.Do(ctx, req, a)
+	if err != nil {
+		return nil, resp, err
+	}
+	return a, resp, nil
+}
+
+// Create a new authorization for the specified OAuth application.
+//
+// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#create-a-new-authorization
+func (s *AuthorizationsService) Create(ctx context.Context, auth *AuthorizationRequest) (*Authorization, *Response, error) {
+	u := "authorizations"
+
+	req, err := s.client.NewRequest("POST", u, auth)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	a := new(Authorization)
+	resp, err := s.client.Do(ctx, req, a)
+	if err != nil {
+		return nil, resp, err
+	}
+	return a, resp, nil
+}
+
+// GetOrCreateForApp creates a new authorization for the specified OAuth
+// application, only if an authorization for that application doesn’t already
+// exist for the user.
+//
+// If a new token is created, the HTTP status code will be "201 Created", and
+// the returned Authorization.Token field will be populated. If an existing
+// token is returned, the status code will be "200 OK" and the
+// Authorization.Token field will be empty.
+//
+// clientID is the OAuth Client ID with which to create the token.
+//
+// GitHub API docs:
+// https://developer.github.com/v3/oauth_authorizations/#get-or-create-an-authorization-for-a-specific-app
+// https://developer.github.com/v3/oauth_authorizations/#get-or-create-an-authorization-for-a-specific-app-and-fingerprint
+func (s *AuthorizationsService) GetOrCreateForApp(ctx context.Context, clientID string, auth *AuthorizationRequest) (*Authorization, *Response, error) {
+	var u string
+	if auth.Fingerprint == nil || *auth.Fingerprint == "" {
+		u = fmt.Sprintf("authorizations/clients/%v", clientID)
+	} else {
+		u = fmt.Sprintf("authorizations/clients/%v/%v", clientID, *auth.Fingerprint)
+	}
+
+	req, err := s.client.NewRequest("PUT", u, auth)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	a := new(Authorization)
+	resp, err := s.client.Do(ctx, req, a)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return a, resp, nil
+}
+
+// Edit a single authorization.
+//
+// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#update-an-existing-authorization
+func (s *AuthorizationsService) Edit(ctx context.Context, id int64, auth *AuthorizationUpdateRequest) (*Authorization, *Response, error) {
+	u := fmt.Sprintf("authorizations/%d", id)
+
+	req, err := s.client.NewRequest("PATCH", u, auth)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	a := new(Authorization)
+	resp, err := s.client.Do(ctx, req, a)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return a, resp, nil
+}
+
+// Delete a single authorization.
+//
+// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#delete-an-authorization
+func (s *AuthorizationsService) Delete(ctx context.Context, id int64) (*Response, error) {
+	u := fmt.Sprintf("authorizations/%d", id)
+
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// Check if an OAuth token is valid for a specific app.
+//
+// Note that this operation requires the use of BasicAuth, but where the
+// username is the OAuth application clientID, and the password is its
+// clientSecret. Invalid tokens will return a 404 Not Found.
+//
+// The returned Authorization.User field will be populated.
+//
+// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#check-an-authorization
+func (s *AuthorizationsService) Check(ctx context.Context, clientID string, token string) (*Authorization, *Response, error) {
+	u := fmt.Sprintf("applications/%v/tokens/%v", clientID, token)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	a := new(Authorization)
+	resp, err := s.client.Do(ctx, req, a)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return a, resp, nil
+}
+
+// Reset is used to reset a valid OAuth token without end user involvement.
+// Applications must save the "token" property in the response, because changes
+// take effect immediately.
+//
+// Note that this operation requires the use of BasicAuth, but where the
+// username is the OAuth application clientID, and the password is its
+// clientSecret. Invalid tokens will return a 404 Not Found.
+//
+// The returned Authorization.User field will be populated.
+//
+// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#reset-an-authorization
+func (s *AuthorizationsService) Reset(ctx context.Context, clientID string, token string) (*Authorization, *Response, error) {
+	u := fmt.Sprintf("applications/%v/tokens/%v", clientID, token)
+
+	req, err := s.client.NewRequest("POST", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	a := new(Authorization)
+	resp, err := s.client.Do(ctx, req, a)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return a, resp, nil
+}
+
+// Revoke an authorization for an application.
+//
+// Note that this operation requires the use of BasicAuth, but where the
+// username is the OAuth application clientID, and the password is its
+// clientSecret. Invalid tokens will return a 404 Not Found.
+//
+// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#revoke-an-authorization-for-an-application
+func (s *AuthorizationsService) Revoke(ctx context.Context, clientID string, token string) (*Response, error) {
+	u := fmt.Sprintf("applications/%v/tokens/%v", clientID, token)
+
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// ListGrants lists the set of OAuth applications that have been granted
+// access to a user's account. This will return one entry for each application
+// that has been granted access to the account, regardless of the number of
+// tokens an application has generated for the user.
+//
+// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#list-your-grants
+func (s *AuthorizationsService) ListGrants(ctx context.Context, opt *ListOptions) ([]*Grant, *Response, error) {
+	u, err := addOptions("applications/grants", opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	grants := []*Grant{}
+	resp, err := s.client.Do(ctx, req, &grants)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return grants, resp, nil
+}
+
+// GetGrant gets a single OAuth application grant.
+//
+// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#get-a-single-grant
+func (s *AuthorizationsService) GetGrant(ctx context.Context, id int64) (*Grant, *Response, error) {
+	u := fmt.Sprintf("applications/grants/%d", id)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	grant := new(Grant)
+	resp, err := s.client.Do(ctx, req, grant)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return grant, resp, nil
+}
+
+// DeleteGrant deletes an OAuth application grant. Deleting an application's
+// grant will also delete all OAuth tokens associated with the application for
+// the user.
+//
+// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#delete-a-grant
+func (s *AuthorizationsService) DeleteGrant(ctx context.Context, id int64) (*Response, error) {
+	u := fmt.Sprintf("applications/grants/%d", id)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// CreateImpersonation creates an impersonation OAuth token.
+//
+// This requires admin permissions. With the returned Authorization.Token
+// you can e.g. create or delete a user's public SSH key. NOTE: creating a
+// new token automatically revokes an existing one.
+//
+// GitHub API docs: https://developer.github.com/enterprise/v3/enterprise-admin/users/#create-an-impersonation-oauth-token
+func (s *AuthorizationsService) CreateImpersonation(ctx context.Context, username string, authReq *AuthorizationRequest) (*Authorization, *Response, error) {
+	u := fmt.Sprintf("admin/users/%v/authorizations", username)
+	req, err := s.client.NewRequest("POST", u, authReq)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	a := new(Authorization)
+	resp, err := s.client.Do(ctx, req, a)
+	if err != nil {
+		return nil, resp, err
+	}
+	return a, resp, nil
+}
+
+// DeleteImpersonation deletes an impersonation OAuth token.
+//
+// NOTE: there can be only one at a time.
+//
+// GitHub API docs: https://developer.github.com/enterprise/v3/enterprise-admin/users/#delete-an-impersonation-oauth-token
+func (s *AuthorizationsService) DeleteImpersonation(ctx context.Context, username string) (*Response, error) {
+	u := fmt.Sprintf("admin/users/%v/authorizations", username)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/checks.go b/vendor/github.com/google/go-github/v24/github/checks.go
new file mode 100644
index 000000000..8aaed8a56
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/checks.go
@@ -0,0 +1,432 @@
+// Copyright 2018 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"net/url"
+)
+
+// ChecksService provides access to the Checks API in the
+// GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/checks/
+type ChecksService service
+
+// CheckRun represents a GitHub check run on a repository associated with a GitHub app.
+type CheckRun struct {
+	ID           *int64          `json:"id,omitempty"`
+	NodeID       *string         `json:"node_id,omitempty"`
+	HeadSHA      *string         `json:"head_sha,omitempty"`
+	ExternalID   *string         `json:"external_id,omitempty"`
+	URL          *string         `json:"url,omitempty"`
+	HTMLURL      *string         `json:"html_url,omitempty"`
+	DetailsURL   *string         `json:"details_url,omitempty"`
+	Status       *string         `json:"status,omitempty"`
+	Conclusion   *string         `json:"conclusion,omitempty"`
+	StartedAt    *Timestamp      `json:"started_at,omitempty"`
+	CompletedAt  *Timestamp      `json:"completed_at,omitempty"`
+	Output       *CheckRunOutput `json:"output,omitempty"`
+	Name         *string         `json:"name,omitempty"`
+	CheckSuite   *CheckSuite     `json:"check_suite,omitempty"`
+	App          *App            `json:"app,omitempty"`
+	PullRequests []*PullRequest  `json:"pull_requests,omitempty"`
+}
+
+// CheckRunOutput represents the output of a CheckRun.
+type CheckRunOutput struct {
+	Title            *string               `json:"title,omitempty"`
+	Summary          *string               `json:"summary,omitempty"`
+	Text             *string               `json:"text,omitempty"`
+	AnnotationsCount *int                  `json:"annotations_count,omitempty"`
+	AnnotationsURL   *string               `json:"annotations_url,omitempty"`
+	Annotations      []*CheckRunAnnotation `json:"annotations,omitempty"`
+	Images           []*CheckRunImage      `json:"images,omitempty"`
+}
+
+// CheckRunAnnotation represents an annotation object for a CheckRun output.
+type CheckRunAnnotation struct {
+	Path            *string `json:"path,omitempty"`
+	BlobHRef        *string `json:"blob_href,omitempty"`
+	StartLine       *int    `json:"start_line,omitempty"`
+	EndLine         *int    `json:"end_line,omitempty"`
+	AnnotationLevel *string `json:"annotation_level,omitempty"`
+	Message         *string `json:"message,omitempty"`
+	Title           *string `json:"title,omitempty"`
+	RawDetails      *string `json:"raw_details,omitempty"`
+}
+
+// CheckRunImage represents an image object for a CheckRun output.
+type CheckRunImage struct {
+	Alt      *string `json:"alt,omitempty"`
+	ImageURL *string `json:"image_url,omitempty"`
+	Caption  *string `json:"caption,omitempty"`
+}
+
+// CheckSuite represents a suite of check runs.
+type CheckSuite struct {
+	ID           *int64         `json:"id,omitempty"`
+	NodeID       *string        `json:"node_id,omitempty"`
+	HeadBranch   *string        `json:"head_branch,omitempty"`
+	HeadSHA      *string        `json:"head_sha,omitempty"`
+	URL          *string        `json:"url,omitempty"`
+	BeforeSHA    *string        `json:"before,omitempty"`
+	AfterSHA     *string        `json:"after,omitempty"`
+	Status       *string        `json:"status,omitempty"`
+	Conclusion   *string        `json:"conclusion,omitempty"`
+	App          *App           `json:"app,omitempty"`
+	Repository   *Repository    `json:"repository,omitempty"`
+	PullRequests []*PullRequest `json:"pull_requests,omitempty"`
+}
+
+func (c CheckRun) String() string {
+	return Stringify(c)
+}
+
+func (c CheckSuite) String() string {
+	return Stringify(c)
+}
+
+// GetCheckRun gets a check-run for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/checks/runs/#get-a-single-check-run
+func (s *ChecksService) GetCheckRun(ctx context.Context, owner, repo string, checkRunID int64) (*CheckRun, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/check-runs/%v", owner, repo, checkRunID)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeCheckRunsPreview)
+
+	checkRun := new(CheckRun)
+	resp, err := s.client.Do(ctx, req, checkRun)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return checkRun, resp, nil
+}
+
+// GetCheckSuite gets a single check suite.
+//
+// GitHub API docs: https://developer.github.com/v3/checks/suites/#get-a-single-check-suite
+func (s *ChecksService) GetCheckSuite(ctx context.Context, owner, repo string, checkSuiteID int64) (*CheckSuite, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/check-suites/%v", owner, repo, checkSuiteID)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeCheckRunsPreview)
+
+	checkSuite := new(CheckSuite)
+	resp, err := s.client.Do(ctx, req, checkSuite)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return checkSuite, resp, nil
+}
+
+// CreateCheckRunOptions sets up parameters needed to create a CheckRun.
+type CreateCheckRunOptions struct {
+	Name        string            `json:"name"`                   // The name of the check (e.g., "code-coverage"). (Required.)
+	HeadBranch  string            `json:"head_branch"`            // The name of the branch to perform a check against. (Required.)
+	HeadSHA     string            `json:"head_sha"`               // The SHA of the commit. (Required.)
+	DetailsURL  *string           `json:"details_url,omitempty"`  // The URL of the integrator's site that has the full details of the check. (Optional.)
+	ExternalID  *string           `json:"external_id,omitempty"`  // A reference for the run on the integrator's system. (Optional.)
+	Status      *string           `json:"status,omitempty"`       // The current status. Can be one of "queued", "in_progress", or "completed". Default: "queued". (Optional.)
+	Conclusion  *string           `json:"conclusion,omitempty"`   // Can be one of "success", "failure", "neutral", "cancelled", "timed_out", or "action_required". (Optional. Required if you provide a status of "completed".)
+	StartedAt   *Timestamp        `json:"started_at,omitempty"`   // The time that the check run began. (Optional.)
+	CompletedAt *Timestamp        `json:"completed_at,omitempty"` // The time the check completed. (Optional. Required if you provide conclusion.)
+	Output      *CheckRunOutput   `json:"output,omitempty"`       // Provide descriptive details about the run. (Optional)
+	Actions     []*CheckRunAction `json:"actions,omitempty"`      // Possible further actions the integrator can perform, which a user may trigger. (Optional.)
+}
+
+// CheckRunAction exposes further actions the integrator can perform, which a user may trigger.
+type CheckRunAction struct {
+	Label       string `json:"label"`       // The text to be displayed on a button in the web UI. The maximum size is 20 characters. (Required.)
+	Description string `json:"description"` // A short explanation of what this action would do. The maximum size is 40 characters. (Required.)
+	Identifier  string `json:"identifier"`  // A reference for the action on the integrator's system. The maximum size is 20 characters. (Required.)
+}
+
+// CreateCheckRun creates a check run for repository.
+//
+// GitHub API docs: https://developer.github.com/v3/checks/runs/#create-a-check-run
+func (s *ChecksService) CreateCheckRun(ctx context.Context, owner, repo string, opt CreateCheckRunOptions) (*CheckRun, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/check-runs", owner, repo)
+	req, err := s.client.NewRequest("POST", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeCheckRunsPreview)
+
+	checkRun := new(CheckRun)
+	resp, err := s.client.Do(ctx, req, checkRun)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return checkRun, resp, nil
+}
+
+// UpdateCheckRunOptions sets up parameters needed to update a CheckRun.
+type UpdateCheckRunOptions struct {
+	Name        string            `json:"name"`                   // The name of the check (e.g., "code-coverage"). (Required.)
+	HeadBranch  *string           `json:"head_branch,omitempty"`  // The name of the branch to perform a check against. (Optional.)
+	HeadSHA     *string           `json:"head_sha,omitempty"`     // The SHA of the commit. (Optional.)
+	DetailsURL  *string           `json:"details_url,omitempty"`  // The URL of the integrator's site that has the full details of the check. (Optional.)
+	ExternalID  *string           `json:"external_id,omitempty"`  // A reference for the run on the integrator's system. (Optional.)
+	Status      *string           `json:"status,omitempty"`       // The current status. Can be one of "queued", "in_progress", or "completed". Default: "queued". (Optional.)
+	Conclusion  *string           `json:"conclusion,omitempty"`   // Can be one of "success", "failure", "neutral", "cancelled", "timed_out", or "action_required". (Optional. Required if you provide a status of "completed".)
+	CompletedAt *Timestamp        `json:"completed_at,omitempty"` // The time the check completed. (Optional. Required if you provide conclusion.)
+	Output      *CheckRunOutput   `json:"output,omitempty"`       // Provide descriptive details about the run. (Optional)
+	Actions     []*CheckRunAction `json:"actions,omitempty"`      // Possible further actions the integrator can perform, which a user may trigger. (Optional.)
+}
+
+// UpdateCheckRun updates a check run for a specific commit in a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/checks/runs/#update-a-check-run
+func (s *ChecksService) UpdateCheckRun(ctx context.Context, owner, repo string, checkRunID int64, opt UpdateCheckRunOptions) (*CheckRun, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/check-runs/%v", owner, repo, checkRunID)
+	req, err := s.client.NewRequest("PATCH", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeCheckRunsPreview)
+
+	checkRun := new(CheckRun)
+	resp, err := s.client.Do(ctx, req, checkRun)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return checkRun, resp, nil
+}
+
+// ListCheckRunAnnotations lists the annotations for a check run.
+//
+// GitHub API docs: https://developer.github.com/v3/checks/runs/#list-annotations-for-a-check-run
+func (s *ChecksService) ListCheckRunAnnotations(ctx context.Context, owner, repo string, checkRunID int64, opt *ListOptions) ([]*CheckRunAnnotation, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/check-runs/%v/annotations", owner, repo, checkRunID)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeCheckRunsPreview)
+
+	var checkRunAnnotations []*CheckRunAnnotation
+	resp, err := s.client.Do(ctx, req, &checkRunAnnotations)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return checkRunAnnotations, resp, nil
+}
+
+// ListCheckRunsOptions represents parameters to list check runs.
+type ListCheckRunsOptions struct {
+	CheckName *string `url:"check_name,omitempty"` // Returns check runs with the specified name.
+	Status    *string `url:"status,omitempty"`     // Returns check runs with the specified status. Can be one of "queued", "in_progress", or "completed".
+	Filter    *string `url:"filter,omitempty"`     // Filters check runs by their completed_at timestamp. Can be one of "latest" (returning the most recent check runs) or "all". Default: "latest"
+
+	ListOptions
+}
+
+// ListCheckRunsResults represents the result of a check run list.
+type ListCheckRunsResults struct {
+	Total     *int        `json:"total_count,omitempty"`
+	CheckRuns []*CheckRun `json:"check_runs,omitempty"`
+}
+
+// ListCheckRunsForRef lists check runs for a specific ref.
+//
+// GitHub API docs: https://developer.github.com/v3/checks/runs/#list-check-runs-for-a-specific-ref
+func (s *ChecksService) ListCheckRunsForRef(ctx context.Context, owner, repo, ref string, opt *ListCheckRunsOptions) (*ListCheckRunsResults, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/commits/%v/check-runs", owner, repo, url.QueryEscape(ref))
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeCheckRunsPreview)
+
+	var checkRunResults *ListCheckRunsResults
+	resp, err := s.client.Do(ctx, req, &checkRunResults)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return checkRunResults, resp, nil
+}
+
+// ListCheckRunsCheckSuite lists check runs for a check suite.
+//
+// GitHub API docs: https://developer.github.com/v3/checks/runs/#list-check-runs-in-a-check-suite
+func (s *ChecksService) ListCheckRunsCheckSuite(ctx context.Context, owner, repo string, checkSuiteID int64, opt *ListCheckRunsOptions) (*ListCheckRunsResults, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/check-suites/%v/check-runs", owner, repo, checkSuiteID)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeCheckRunsPreview)
+
+	var checkRunResults *ListCheckRunsResults
+	resp, err := s.client.Do(ctx, req, &checkRunResults)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return checkRunResults, resp, nil
+}
+
+// ListCheckSuiteOptions represents parameters to list check suites.
+type ListCheckSuiteOptions struct {
+	CheckName *string `url:"check_name,omitempty"` // Filters checks suites by the name of the check run.
+	AppID     *int    `url:"app_id,omitempty"`     // Filters check suites by GitHub App id.
+
+	ListOptions
+}
+
+// ListCheckSuiteResults represents the result of a check run list.
+type ListCheckSuiteResults struct {
+	Total       *int          `json:"total_count,omitempty"`
+	CheckSuites []*CheckSuite `json:"check_suites,omitempty"`
+}
+
+// ListCheckSuitesForRef lists check suite for a specific ref.
+//
+// GitHub API docs: https://developer.github.com/v3/checks/suites/#list-check-suites-for-a-specific-ref
+func (s *ChecksService) ListCheckSuitesForRef(ctx context.Context, owner, repo, ref string, opt *ListCheckSuiteOptions) (*ListCheckSuiteResults, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/commits/%v/check-suites", owner, repo, url.QueryEscape(ref))
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeCheckRunsPreview)
+
+	var checkSuiteResults *ListCheckSuiteResults
+	resp, err := s.client.Do(ctx, req, &checkSuiteResults)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return checkSuiteResults, resp, nil
+}
+
+// AutoTriggerCheck enables or disables automatic creation of CheckSuite events upon pushes to the repository.
+type AutoTriggerCheck struct {
+	AppID   *int64 `json:"app_id,omitempty"`  // The id of the GitHub App. (Required.)
+	Setting *bool  `json:"setting,omitempty"` // Set to "true" to enable automatic creation of CheckSuite events upon pushes to the repository, or "false" to disable them. Default: "true" (Required.)
+}
+
+// CheckSuitePreferenceOptions set options for check suite preferences for a repository.
+type CheckSuitePreferenceOptions struct {
+	PreferenceList *PreferenceList `json:"auto_trigger_checks,omitempty"` // A list of auto trigger checks that can be set for a check suite in a repository.
+}
+
+// CheckSuitePreferenceResults represents the results of the preference set operation.
+type CheckSuitePreferenceResults struct {
+	Preferences *PreferenceList `json:"preferences,omitempty"`
+	Repository  *Repository     `json:"repository,omitempty"`
+}
+
+// PreferenceList represents a list of auto trigger checks for  repository
+type PreferenceList struct {
+	AutoTriggerChecks []*AutoTriggerCheck `json:"auto_trigger_checks,omitempty"` // A slice of auto trigger checks that can be set for a check suite in a repository.
+}
+
+// SetCheckSuitePreferences changes the default automatic flow when creating check suites.
+//
+// GitHub API docs: https://developer.github.com/v3/checks/suites/#set-preferences-for-check-suites-on-a-repository
+func (s *ChecksService) SetCheckSuitePreferences(ctx context.Context, owner, repo string, opt CheckSuitePreferenceOptions) (*CheckSuitePreferenceResults, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/check-suites/preferences", owner, repo)
+	req, err := s.client.NewRequest("PATCH", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeCheckRunsPreview)
+
+	var checkSuitePrefResults *CheckSuitePreferenceResults
+	resp, err := s.client.Do(ctx, req, &checkSuitePrefResults)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return checkSuitePrefResults, resp, nil
+}
+
+// CreateCheckSuiteOptions sets up parameters to manually create a check suites
+type CreateCheckSuiteOptions struct {
+	HeadSHA    string  `json:"head_sha"`              // The sha of the head commit. (Required.)
+	HeadBranch *string `json:"head_branch,omitempty"` // The name of the head branch where the code changes are implemented.
+}
+
+// CreateCheckSuite manually creates a check suite for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/checks/suites/#create-a-check-suite
+func (s *ChecksService) CreateCheckSuite(ctx context.Context, owner, repo string, opt CreateCheckSuiteOptions) (*CheckSuite, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/check-suites", owner, repo)
+	req, err := s.client.NewRequest("POST", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeCheckRunsPreview)
+
+	checkSuite := new(CheckSuite)
+	resp, err := s.client.Do(ctx, req, checkSuite)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return checkSuite, resp, nil
+}
+
+// ReRequestCheckSuite triggers GitHub to rerequest an existing check suite, without pushing new code to a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/checks/suites/#rerequest-check-suite
+func (s *ChecksService) ReRequestCheckSuite(ctx context.Context, owner, repo string, checkSuiteID int64) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/check-suites/%v/rerequest", owner, repo, checkSuiteID)
+
+	req, err := s.client.NewRequest("POST", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeCheckRunsPreview)
+
+	resp, err := s.client.Do(ctx, req, nil)
+	return resp, err
+}
diff --git a/vendor/github.com/google/go-github/v24/github/doc.go b/vendor/github.com/google/go-github/v24/github/doc.go
new file mode 100644
index 000000000..21dc231d7
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/doc.go
@@ -0,0 +1,188 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Package github provides a client for using the GitHub API.
+
+Usage:
+
+	import "github.com/google/go-github/v24/github"	// with go modules enabled (GO111MODULE=on or outside GOPATH)
+	import "github.com/google/go-github/github"     // with go modules disabled
+
+Construct a new GitHub client, then use the various services on the client to
+access different parts of the GitHub API. For example:
+
+	client := github.NewClient(nil)
+
+	// list all organizations for user "willnorris"
+	orgs, _, err := client.Organizations.List(ctx, "willnorris", nil)
+
+Some API methods have optional parameters that can be passed. For example:
+
+	client := github.NewClient(nil)
+
+	// list public repositories for org "github"
+	opt := &github.RepositoryListByOrgOptions{Type: "public"}
+	repos, _, err := client.Repositories.ListByOrg(ctx, "github", opt)
+
+The services of a client divide the API into logical chunks and correspond to
+the structure of the GitHub API documentation at
+https://developer.github.com/v3/.
+
+NOTE: Using the https://godoc.org/context package, one can easily
+pass cancelation signals and deadlines to various services of the client for
+handling a request. In case there is no context available, then context.Background()
+can be used as a starting point.
+
+For more sample code snippets, head over to the https://github.com/google/go-github/tree/master/example directory.
+
+Authentication
+
+The go-github library does not directly handle authentication. Instead, when
+creating a new client, pass an http.Client that can handle authentication for
+you. The easiest and recommended way to do this is using the golang.org/x/oauth2
+library, but you can always use any other library that provides an http.Client.
+If you have an OAuth2 access token (for example, a personal API token), you can
+use it with the oauth2 library using:
+
+	import "golang.org/x/oauth2"
+
+	func main() {
+		ctx := context.Background()
+		ts := oauth2.StaticTokenSource(
+			&oauth2.Token{AccessToken: "... your access token ..."},
+		)
+		tc := oauth2.NewClient(ctx, ts)
+
+		client := github.NewClient(tc)
+
+		// list all repositories for the authenticated user
+		repos, _, err := client.Repositories.List(ctx, "", nil)
+	}
+
+Note that when using an authenticated Client, all calls made by the client will
+include the specified OAuth token. Therefore, authenticated clients should
+almost never be shared between different users.
+
+See the oauth2 docs for complete instructions on using that library.
+
+For API methods that require HTTP Basic Authentication, use the
+BasicAuthTransport.
+
+GitHub Apps authentication can be provided by the
+https://github.com/bradleyfalzon/ghinstallation package.
+
+	import "github.com/bradleyfalzon/ghinstallation"
+
+	func main() {
+		// Wrap the shared transport for use with the integration ID 1 authenticating with installation ID 99.
+		itr, err := ghinstallation.NewKeyFromFile(http.DefaultTransport, 1, 99, "2016-10-19.private-key.pem")
+		if err != nil {
+			// Handle error.
+		}
+
+		// Use installation transport with client
+		client := github.NewClient(&http.Client{Transport: itr})
+
+		// Use client...
+	}
+
+Rate Limiting
+
+GitHub imposes a rate limit on all API clients. Unauthenticated clients are
+limited to 60 requests per hour, while authenticated clients can make up to
+5,000 requests per hour. The Search API has a custom rate limit. Unauthenticated
+clients are limited to 10 requests per minute, while authenticated clients
+can make up to 30 requests per minute. To receive the higher rate limit when
+making calls that are not issued on behalf of a user,
+use UnauthenticatedRateLimitedTransport.
+
+The returned Response.Rate value contains the rate limit information
+from the most recent API call. If a recent enough response isn't
+available, you can use RateLimits to fetch the most up-to-date rate
+limit data for the client.
+
+To detect an API rate limit error, you can check if its type is *github.RateLimitError:
+
+	repos, _, err := client.Repositories.List(ctx, "", nil)
+	if _, ok := err.(*github.RateLimitError); ok {
+		log.Println("hit rate limit")
+	}
+
+Learn more about GitHub rate limiting at
+https://developer.github.com/v3/#rate-limiting.
+
+Accepted Status
+
+Some endpoints may return a 202 Accepted status code, meaning that the
+information required is not yet ready and was scheduled to be gathered on
+the GitHub side. Methods known to behave like this are documented specifying
+this behavior.
+
+To detect this condition of error, you can check if its type is
+*github.AcceptedError:
+
+	stats, _, err := client.Repositories.ListContributorsStats(ctx, org, repo)
+	if _, ok := err.(*github.AcceptedError); ok {
+		log.Println("scheduled on GitHub side")
+	}
+
+Conditional Requests
+
+The GitHub API has good support for conditional requests which will help
+prevent you from burning through your rate limit, as well as help speed up your
+application. go-github does not handle conditional requests directly, but is
+instead designed to work with a caching http.Transport. We recommend using
+https://github.com/gregjones/httpcache for that.
+
+Learn more about GitHub conditional requests at
+https://developer.github.com/v3/#conditional-requests.
+
+Creating and Updating Resources
+
+All structs for GitHub resources use pointer values for all non-repeated fields.
+This allows distinguishing between unset fields and those set to a zero-value.
+Helper functions have been provided to easily create these pointers for string,
+bool, and int values. For example:
+
+	// create a new private repository named "foo"
+	repo := &github.Repository{
+		Name:    github.String("foo"),
+		Private: github.Bool(true),
+	}
+	client.Repositories.Create(ctx, "", repo)
+
+Users who have worked with protocol buffers should find this pattern familiar.
+
+Pagination
+
+All requests for resource collections (repos, pull requests, issues, etc.)
+support pagination. Pagination options are described in the
+github.ListOptions struct and passed to the list methods directly or as an
+embedded type of a more specific list options struct (for example
+github.PullRequestListOptions). Pages information is available via the
+github.Response struct.
+
+	client := github.NewClient(nil)
+
+	opt := &github.RepositoryListByOrgOptions{
+		ListOptions: github.ListOptions{PerPage: 10},
+	}
+	// get all pages of results
+	var allRepos []*github.Repository
+	for {
+		repos, resp, err := client.Repositories.ListByOrg(ctx, "github", opt)
+		if err != nil {
+			return err
+		}
+		allRepos = append(allRepos, repos...)
+		if resp.NextPage == 0 {
+			break
+		}
+		opt.Page = resp.NextPage
+	}
+
+*/
+package github
diff --git a/vendor/github.com/google/go-github/v24/github/event.go b/vendor/github.com/google/go-github/v24/github/event.go
new file mode 100644
index 000000000..04c8845a1
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/event.go
@@ -0,0 +1,126 @@
+// Copyright 2018 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"encoding/json"
+	"time"
+)
+
+// Event represents a GitHub event.
+type Event struct {
+	Type       *string          `json:"type,omitempty"`
+	Public     *bool            `json:"public,omitempty"`
+	RawPayload *json.RawMessage `json:"payload,omitempty"`
+	Repo       *Repository      `json:"repo,omitempty"`
+	Actor      *User            `json:"actor,omitempty"`
+	Org        *Organization    `json:"org,omitempty"`
+	CreatedAt  *time.Time       `json:"created_at,omitempty"`
+	ID         *string          `json:"id,omitempty"`
+}
+
+func (e Event) String() string {
+	return Stringify(e)
+}
+
+// ParsePayload parses the event payload. For recognized event types,
+// a value of the corresponding struct type will be returned.
+func (e *Event) ParsePayload() (payload interface{}, err error) {
+	switch *e.Type {
+	case "CheckRunEvent":
+		payload = &CheckRunEvent{}
+	case "CheckSuiteEvent":
+		payload = &CheckSuiteEvent{}
+	case "CommitCommentEvent":
+		payload = &CommitCommentEvent{}
+	case "CreateEvent":
+		payload = &CreateEvent{}
+	case "DeleteEvent":
+		payload = &DeleteEvent{}
+	case "DeploymentEvent":
+		payload = &DeploymentEvent{}
+	case "DeploymentStatusEvent":
+		payload = &DeploymentStatusEvent{}
+	case "ForkEvent":
+		payload = &ForkEvent{}
+	case "GitHubAppAuthorizationEvent":
+		payload = &GitHubAppAuthorizationEvent{}
+	case "GollumEvent":
+		payload = &GollumEvent{}
+	case "InstallationEvent":
+		payload = &InstallationEvent{}
+	case "InstallationRepositoriesEvent":
+		payload = &InstallationRepositoriesEvent{}
+	case "IssueCommentEvent":
+		payload = &IssueCommentEvent{}
+	case "IssuesEvent":
+		payload = &IssuesEvent{}
+	case "LabelEvent":
+		payload = &LabelEvent{}
+	case "MarketplacePurchaseEvent":
+		payload = &MarketplacePurchaseEvent{}
+	case "MemberEvent":
+		payload = &MemberEvent{}
+	case "MembershipEvent":
+		payload = &MembershipEvent{}
+	case "MilestoneEvent":
+		payload = &MilestoneEvent{}
+	case "OrganizationEvent":
+		payload = &OrganizationEvent{}
+	case "OrgBlockEvent":
+		payload = &OrgBlockEvent{}
+	case "PageBuildEvent":
+		payload = &PageBuildEvent{}
+	case "PingEvent":
+		payload = &PingEvent{}
+	case "ProjectEvent":
+		payload = &ProjectEvent{}
+	case "ProjectCardEvent":
+		payload = &ProjectCardEvent{}
+	case "ProjectColumnEvent":
+		payload = &ProjectColumnEvent{}
+	case "PublicEvent":
+		payload = &PublicEvent{}
+	case "PullRequestEvent":
+		payload = &PullRequestEvent{}
+	case "PullRequestReviewEvent":
+		payload = &PullRequestReviewEvent{}
+	case "PullRequestReviewCommentEvent":
+		payload = &PullRequestReviewCommentEvent{}
+	case "PushEvent":
+		payload = &PushEvent{}
+	case "ReleaseEvent":
+		payload = &ReleaseEvent{}
+	case "RepositoryEvent":
+		payload = &RepositoryEvent{}
+	case "RepositoryVulnerabilityAlertEvent":
+		payload = &RepositoryVulnerabilityAlertEvent{}
+	case "StatusEvent":
+		payload = &StatusEvent{}
+	case "TeamEvent":
+		payload = &TeamEvent{}
+	case "TeamAddEvent":
+		payload = &TeamAddEvent{}
+	case "WatchEvent":
+		payload = &WatchEvent{}
+	}
+	err = json.Unmarshal(*e.RawPayload, &payload)
+	return payload, err
+}
+
+// Payload returns the parsed event payload. For recognized event types,
+// a value of the corresponding struct type will be returned.
+//
+// Deprecated: Use ParsePayload instead, which returns an error
+// rather than panics if JSON unmarshaling raw payload fails.
+func (e *Event) Payload() (payload interface{}) {
+	var err error
+	payload, err = e.ParsePayload()
+	if err != nil {
+		panic(err)
+	}
+	return payload
+}
diff --git a/vendor/github.com/google/go-github/v24/github/event_types.go b/vendor/github.com/google/go-github/v24/github/event_types.go
new file mode 100644
index 000000000..0d70a474c
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/event_types.go
@@ -0,0 +1,833 @@
+// Copyright 2016 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// These event types are shared between the Events API and used as Webhook payloads.
+
+package github
+
+// RequestedAction is included in a CheckRunEvent when a user has invoked an action,
+// i.e. when the CheckRunEvent's Action field is "requested_action".
+type RequestedAction struct {
+	Identifier string `json:"identifier"` // The integrator reference of the action requested by the user.
+}
+
+// CheckRunEvent is triggered when a check run is "created", "updated", or "re-requested".
+// The Webhook event name is "check_run".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#checkrunevent
+type CheckRunEvent struct {
+	CheckRun *CheckRun `json:"check_run,omitempty"`
+	// The action performed. Can be "created", "updated", "rerequested" or "requested_action".
+	Action *string `json:"action,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Repo         *Repository   `json:"repository,omitempty"`
+	Org          *Organization `json:"organization,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+
+	// The action requested by the user. Populated when the Action is "requested_action".
+	RequestedAction *RequestedAction `json:"requested_action,omitempty"` //
+}
+
+// CheckSuiteEvent is triggered when a check suite is "completed", "requested", or "re-requested".
+// The Webhook event name is "check_suite".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#checksuiteevent
+type CheckSuiteEvent struct {
+	CheckSuite *CheckSuite `json:"check_suite,omitempty"`
+	// The action performed. Can be "completed", "requested" or "re-requested".
+	Action *string `json:"action,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Repo         *Repository   `json:"repository,omitempty"`
+	Org          *Organization `json:"organization,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// CommitCommentEvent is triggered when a commit comment is created.
+// The Webhook event name is "commit_comment".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#commitcommentevent
+type CommitCommentEvent struct {
+	Comment *RepositoryComment `json:"comment,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Action       *string       `json:"action,omitempty"`
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// CreateEvent represents a created repository, branch, or tag.
+// The Webhook event name is "create".
+//
+// Note: webhooks will not receive this event for created repositories.
+// Additionally, webhooks will not receive this event for tags if more
+// than three tags are pushed at once.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#createevent
+type CreateEvent struct {
+	Ref *string `json:"ref,omitempty"`
+	// RefType is the object that was created. Possible values are: "repository", "branch", "tag".
+	RefType      *string `json:"ref_type,omitempty"`
+	MasterBranch *string `json:"master_branch,omitempty"`
+	Description  *string `json:"description,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	PusherType   *string       `json:"pusher_type,omitempty"`
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// DeleteEvent represents a deleted branch or tag.
+// The Webhook event name is "delete".
+//
+// Note: webhooks will not receive this event for tags if more than three tags
+// are deleted at once.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#deleteevent
+type DeleteEvent struct {
+	Ref *string `json:"ref,omitempty"`
+	// RefType is the object that was deleted. Possible values are: "branch", "tag".
+	RefType *string `json:"ref_type,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	PusherType   *string       `json:"pusher_type,omitempty"`
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// DeploymentEvent represents a deployment.
+// The Webhook event name is "deployment".
+//
+// Events of this type are not visible in timelines, they are only used to trigger hooks.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#deploymentevent
+type DeploymentEvent struct {
+	Deployment *Deployment `json:"deployment,omitempty"`
+	Repo       *Repository `json:"repository,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// DeploymentStatusEvent represents a deployment status.
+// The Webhook event name is "deployment_status".
+//
+// Events of this type are not visible in timelines, they are only used to trigger hooks.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#deploymentstatusevent
+type DeploymentStatusEvent struct {
+	Deployment       *Deployment       `json:"deployment,omitempty"`
+	DeploymentStatus *DeploymentStatus `json:"deployment_status,omitempty"`
+	Repo             *Repository       `json:"repository,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// ForkEvent is triggered when a user forks a repository.
+// The Webhook event name is "fork".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#forkevent
+type ForkEvent struct {
+	// Forkee is the created repository.
+	Forkee *Repository `json:"forkee,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// GitHubAppAuthorizationEvent is triggered when a user's authorization for a
+// GitHub Application is revoked.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#githubappauthorizationevent
+type GitHubAppAuthorizationEvent struct {
+	// The action performed. Can be "revoked".
+	Action *string `json:"action,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Sender *User `json:"sender,omitempty"`
+}
+
+// Page represents a single Wiki page.
+type Page struct {
+	PageName *string `json:"page_name,omitempty"`
+	Title    *string `json:"title,omitempty"`
+	Summary  *string `json:"summary,omitempty"`
+	Action   *string `json:"action,omitempty"`
+	SHA      *string `json:"sha,omitempty"`
+	HTMLURL  *string `json:"html_url,omitempty"`
+}
+
+// GollumEvent is triggered when a Wiki page is created or updated.
+// The Webhook event name is "gollum".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#gollumevent
+type GollumEvent struct {
+	Pages []*Page `json:"pages,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// EditChange represents the changes when an issue, pull request, or comment has
+// been edited.
+type EditChange struct {
+	Title *struct {
+		From *string `json:"from,omitempty"`
+	} `json:"title,omitempty"`
+	Body *struct {
+		From *string `json:"from,omitempty"`
+	} `json:"body,omitempty"`
+}
+
+// ProjectChange represents the changes when a project has been edited.
+type ProjectChange struct {
+	Name *struct {
+		From *string `json:"from,omitempty"`
+	} `json:"name,omitempty"`
+	Body *struct {
+		From *string `json:"from,omitempty"`
+	} `json:"body,omitempty"`
+}
+
+// ProjectCardChange represents the changes when a project card has been edited.
+type ProjectCardChange struct {
+	Note *struct {
+		From *string `json:"from,omitempty"`
+	} `json:"note,omitempty"`
+}
+
+// ProjectColumnChange represents the changes when a project column has been edited.
+type ProjectColumnChange struct {
+	Name *struct {
+		From *string `json:"from,omitempty"`
+	} `json:"name,omitempty"`
+}
+
+// TeamChange represents the changes when a team has been edited.
+type TeamChange struct {
+	Description *struct {
+		From *string `json:"from,omitempty"`
+	} `json:"description,omitempty"`
+	Name *struct {
+		From *string `json:"from,omitempty"`
+	} `json:"name,omitempty"`
+	Privacy *struct {
+		From *string `json:"from,omitempty"`
+	} `json:"privacy,omitempty"`
+	Repository *struct {
+		Permissions *struct {
+			From *struct {
+				Admin *bool `json:"admin,omitempty"`
+				Pull  *bool `json:"pull,omitempty"`
+				Push  *bool `json:"push,omitempty"`
+			} `json:"from,omitempty"`
+		} `json:"permissions,omitempty"`
+	} `json:"repository,omitempty"`
+}
+
+// InstallationEvent is triggered when a GitHub App has been installed or uninstalled.
+// The Webhook event name is "installation".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#installationevent
+type InstallationEvent struct {
+	// The action that was performed. Can be either "created" or "deleted".
+	Action       *string       `json:"action,omitempty"`
+	Repositories []*Repository `json:"repositories,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// InstallationRepositoriesEvent is triggered when a repository is added or
+// removed from an installation. The Webhook event name is "installation_repositories".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#installationrepositoriesevent
+type InstallationRepositoriesEvent struct {
+	// The action that was performed. Can be either "added" or "removed".
+	Action              *string       `json:"action,omitempty"`
+	RepositoriesAdded   []*Repository `json:"repositories_added,omitempty"`
+	RepositoriesRemoved []*Repository `json:"repositories_removed,omitempty"`
+	RepositorySelection *string       `json:"repository_selection,omitempty"`
+	Sender              *User         `json:"sender,omitempty"`
+	Installation        *Installation `json:"installation,omitempty"`
+}
+
+// IssueCommentEvent is triggered when an issue comment is created on an issue
+// or pull request.
+// The Webhook event name is "issue_comment".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#issuecommentevent
+type IssueCommentEvent struct {
+	// Action is the action that was performed on the comment.
+	// Possible values are: "created", "edited", "deleted".
+	Action  *string       `json:"action,omitempty"`
+	Issue   *Issue        `json:"issue,omitempty"`
+	Comment *IssueComment `json:"comment,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Changes      *EditChange   `json:"changes,omitempty"`
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// IssuesEvent is triggered when an issue is assigned, unassigned, labeled,
+// unlabeled, opened, closed, or reopened.
+// The Webhook event name is "issues".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#issuesevent
+type IssuesEvent struct {
+	// Action is the action that was performed. Possible values are: "assigned",
+	// "unassigned", "labeled", "unlabeled", "opened", "closed", "reopened", "edited".
+	Action   *string `json:"action,omitempty"`
+	Issue    *Issue  `json:"issue,omitempty"`
+	Assignee *User   `json:"assignee,omitempty"`
+	Label    *Label  `json:"label,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Changes      *EditChange   `json:"changes,omitempty"`
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// LabelEvent is triggered when a repository's label is created, edited, or deleted.
+// The Webhook event name is "label"
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#labelevent
+type LabelEvent struct {
+	// Action is the action that was performed. Possible values are:
+	// "created", "edited", "deleted"
+	Action *string `json:"action,omitempty"`
+	Label  *Label  `json:"label,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Changes      *EditChange   `json:"changes,omitempty"`
+	Repo         *Repository   `json:"repository,omitempty"`
+	Org          *Organization `json:"organization,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// MarketplacePurchaseEvent is triggered when a user purchases, cancels, or changes
+// their GitHub Marketplace plan.
+// Webhook event name "marketplace_purchase".
+//
+// Github API docs: https://developer.github.com/v3/activity/events/types/#marketplacepurchaseevent
+type MarketplacePurchaseEvent struct {
+	// Action is the action that was performed. Possible values are:
+	// "purchased", "cancelled", "pending_change", "pending_change_cancelled", "changed".
+	Action *string `json:"action,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	EffectiveDate               *Timestamp           `json:"effective_date,omitempty"`
+	MarketplacePurchase         *MarketplacePurchase `json:"marketplace_purchase,omitempty"`
+	PreviousMarketplacePurchase *MarketplacePurchase `json:"previous_marketplace_purchase,omitempty"`
+	Sender                      *User                `json:"sender,omitempty"`
+	Installation                *Installation        `json:"installation,omitempty"`
+}
+
+// MemberEvent is triggered when a user is added as a collaborator to a repository.
+// The Webhook event name is "member".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#memberevent
+type MemberEvent struct {
+	// Action is the action that was performed. Possible value is: "added".
+	Action *string `json:"action,omitempty"`
+	Member *User   `json:"member,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// MembershipEvent is triggered when a user is added or removed from a team.
+// The Webhook event name is "membership".
+//
+// Events of this type are not visible in timelines, they are only used to
+// trigger organization webhooks.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#membershipevent
+type MembershipEvent struct {
+	// Action is the action that was performed. Possible values are: "added", "removed".
+	Action *string `json:"action,omitempty"`
+	// Scope is the scope of the membership. Possible value is: "team".
+	Scope  *string `json:"scope,omitempty"`
+	Member *User   `json:"member,omitempty"`
+	Team   *Team   `json:"team,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Org          *Organization `json:"organization,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// MilestoneEvent is triggered when a milestone is created, closed, opened, edited, or deleted.
+// The Webhook event name is "milestone".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#milestoneevent
+type MilestoneEvent struct {
+	// Action is the action that was performed. Possible values are:
+	// "created", "closed", "opened", "edited", "deleted"
+	Action    *string    `json:"action,omitempty"`
+	Milestone *Milestone `json:"milestone,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Changes      *EditChange   `json:"changes,omitempty"`
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Org          *Organization `json:"organization,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// OrganizationEvent is triggered when a user is added, removed, or invited to an organization.
+// Events of this type are not visible in timelines. These events are only used to trigger organization hooks.
+// Webhook event name is "organization".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#organizationevent
+type OrganizationEvent struct {
+	// Action is the action that was performed.
+	// Can be one of "member_added", "member_removed", or "member_invited".
+	Action *string `json:"action,omitempty"`
+
+	// Invitaion is the invitation for the user or email if the action is "member_invited".
+	Invitation *Invitation `json:"invitation,omitempty"`
+
+	// Membership is the membership between the user and the organization.
+	// Not present when the action is "member_invited".
+	Membership *Membership `json:"membership,omitempty"`
+
+	Organization *Organization `json:"organization,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// OrgBlockEvent is triggered when an organization blocks or unblocks a user.
+// The Webhook event name is "org_block".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#orgblockevent
+type OrgBlockEvent struct {
+	// Action is the action that was performed.
+	// Can be "blocked" or "unblocked".
+	Action       *string       `json:"action,omitempty"`
+	BlockedUser  *User         `json:"blocked_user,omitempty"`
+	Organization *Organization `json:"organization,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// PageBuildEvent represents an attempted build of a GitHub Pages site, whether
+// successful or not.
+// The Webhook event name is "page_build".
+//
+// This event is triggered on push to a GitHub Pages enabled branch (gh-pages
+// for project pages, master for user and organization pages).
+//
+// Events of this type are not visible in timelines, they are only used to trigger hooks.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#pagebuildevent
+type PageBuildEvent struct {
+	Build *PagesBuild `json:"build,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	ID           *int64        `json:"id,omitempty"`
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// PingEvent is triggered when a Webhook is added to GitHub.
+//
+// GitHub API docs: https://developer.github.com/webhooks/#ping-event
+type PingEvent struct {
+	// Random string of GitHub zen.
+	Zen *string `json:"zen,omitempty"`
+	// The ID of the webhook that triggered the ping.
+	HookID *int64 `json:"hook_id,omitempty"`
+	// The webhook configuration.
+	Hook         *Hook         `json:"hook,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// ProjectEvent is triggered when project is created, modified or deleted.
+// The webhook event name is "project".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#projectevent
+type ProjectEvent struct {
+	Action  *string        `json:"action,omitempty"`
+	Changes *ProjectChange `json:"changes,omitempty"`
+	Project *Project       `json:"project,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Repo         *Repository   `json:"repository,omitempty"`
+	Org          *Organization `json:"organization,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// ProjectCardEvent is triggered when a project card is created, updated, moved, converted to an issue, or deleted.
+// The webhook event name is "project_card".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#projectcardevent
+type ProjectCardEvent struct {
+	Action      *string            `json:"action,omitempty"`
+	Changes     *ProjectCardChange `json:"changes,omitempty"`
+	AfterID     *int64             `json:"after_id,omitempty"`
+	ProjectCard *ProjectCard       `json:"project_card,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Repo         *Repository   `json:"repository,omitempty"`
+	Org          *Organization `json:"organization,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// ProjectColumnEvent is triggered when a project column is created, updated, moved, or deleted.
+// The webhook event name is "project_column".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#projectcolumnevent
+type ProjectColumnEvent struct {
+	Action        *string              `json:"action,omitempty"`
+	Changes       *ProjectColumnChange `json:"changes,omitempty"`
+	AfterID       *int64               `json:"after_id,omitempty"`
+	ProjectColumn *ProjectColumn       `json:"project_column,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Repo         *Repository   `json:"repository,omitempty"`
+	Org          *Organization `json:"organization,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// PublicEvent is triggered when a private repository is open sourced.
+// According to GitHub: "Without a doubt: the best GitHub event."
+// The Webhook event name is "public".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#publicevent
+type PublicEvent struct {
+	// The following fields are only populated by Webhook events.
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// PullRequestEvent is triggered when a pull request is assigned, unassigned,
+// labeled, unlabeled, opened, closed, reopened, or synchronized.
+// The Webhook event name is "pull_request".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#pullrequestevent
+type PullRequestEvent struct {
+	// Action is the action that was performed. Possible values are:
+	// "assigned", "unassigned", "review_requested", "review_request_removed", "labeled", "unlabeled",
+	// "opened", "closed", "reopened", "synchronize", "edited".
+	// If the action is "closed" and the merged key is false,
+	// the pull request was closed with unmerged commits. If the action is "closed"
+	// and the merged key is true, the pull request was merged.
+	Action      *string      `json:"action,omitempty"`
+	Assignee    *User        `json:"assignee,omitempty"`
+	Number      *int         `json:"number,omitempty"`
+	PullRequest *PullRequest `json:"pull_request,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Changes *EditChange `json:"changes,omitempty"`
+	// RequestedReviewer is populated in "review_requested", "review_request_removed" event deliveries.
+	// A request affecting multiple reviewers at once is split into multiple
+	// such event deliveries, each with a single, different RequestedReviewer.
+	RequestedReviewer *User         `json:"requested_reviewer,omitempty"`
+	Repo              *Repository   `json:"repository,omitempty"`
+	Sender            *User         `json:"sender,omitempty"`
+	Installation      *Installation `json:"installation,omitempty"`
+	Label             *Label        `json:"label,omitempty"` // Populated in "labeled" event deliveries.
+
+	// The following field is only present when the webhook is triggered on
+	// a repository belonging to an organization.
+	Organization *Organization `json:"organization,omitempty"`
+}
+
+// PullRequestReviewEvent is triggered when a review is submitted on a pull
+// request.
+// The Webhook event name is "pull_request_review".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#pullrequestreviewevent
+type PullRequestReviewEvent struct {
+	// Action is always "submitted".
+	Action      *string            `json:"action,omitempty"`
+	Review      *PullRequestReview `json:"review,omitempty"`
+	PullRequest *PullRequest       `json:"pull_request,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+
+	// The following field is only present when the webhook is triggered on
+	// a repository belonging to an organization.
+	Organization *Organization `json:"organization,omitempty"`
+}
+
+// PullRequestReviewCommentEvent is triggered when a comment is created on a
+// portion of the unified diff of a pull request.
+// The Webhook event name is "pull_request_review_comment".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#pullrequestreviewcommentevent
+type PullRequestReviewCommentEvent struct {
+	// Action is the action that was performed on the comment.
+	// Possible values are: "created", "edited", "deleted".
+	Action      *string             `json:"action,omitempty"`
+	PullRequest *PullRequest        `json:"pull_request,omitempty"`
+	Comment     *PullRequestComment `json:"comment,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Changes      *EditChange   `json:"changes,omitempty"`
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// PushEvent represents a git push to a GitHub repository.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#pushevent
+type PushEvent struct {
+	PushID       *int64            `json:"push_id,omitempty"`
+	Head         *string           `json:"head,omitempty"`
+	Ref          *string           `json:"ref,omitempty"`
+	Size         *int              `json:"size,omitempty"`
+	Commits      []PushEventCommit `json:"commits,omitempty"`
+	Before       *string           `json:"before,omitempty"`
+	DistinctSize *int              `json:"distinct_size,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	After        *string              `json:"after,omitempty"`
+	Created      *bool                `json:"created,omitempty"`
+	Deleted      *bool                `json:"deleted,omitempty"`
+	Forced       *bool                `json:"forced,omitempty"`
+	BaseRef      *string              `json:"base_ref,omitempty"`
+	Compare      *string              `json:"compare,omitempty"`
+	Repo         *PushEventRepository `json:"repository,omitempty"`
+	HeadCommit   *PushEventCommit     `json:"head_commit,omitempty"`
+	Pusher       *User                `json:"pusher,omitempty"`
+	Sender       *User                `json:"sender,omitempty"`
+	Installation *Installation        `json:"installation,omitempty"`
+}
+
+func (p PushEvent) String() string {
+	return Stringify(p)
+}
+
+// PushEventCommit represents a git commit in a GitHub PushEvent.
+type PushEventCommit struct {
+	Message  *string       `json:"message,omitempty"`
+	Author   *CommitAuthor `json:"author,omitempty"`
+	URL      *string       `json:"url,omitempty"`
+	Distinct *bool         `json:"distinct,omitempty"`
+
+	// The following fields are only populated by Events API.
+	SHA *string `json:"sha,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	ID        *string       `json:"id,omitempty"`
+	TreeID    *string       `json:"tree_id,omitempty"`
+	Timestamp *Timestamp    `json:"timestamp,omitempty"`
+	Committer *CommitAuthor `json:"committer,omitempty"`
+	Added     []string      `json:"added,omitempty"`
+	Removed   []string      `json:"removed,omitempty"`
+	Modified  []string      `json:"modified,omitempty"`
+}
+
+func (p PushEventCommit) String() string {
+	return Stringify(p)
+}
+
+// PushEventRepository represents the repo object in a PushEvent payload.
+type PushEventRepository struct {
+	ID              *int64     `json:"id,omitempty"`
+	NodeID          *string    `json:"node_id,omitempty"`
+	Name            *string    `json:"name,omitempty"`
+	FullName        *string    `json:"full_name,omitempty"`
+	Owner           *User      `json:"owner,omitempty"`
+	Private         *bool      `json:"private,omitempty"`
+	Description     *string    `json:"description,omitempty"`
+	Fork            *bool      `json:"fork,omitempty"`
+	CreatedAt       *Timestamp `json:"created_at,omitempty"`
+	PushedAt        *Timestamp `json:"pushed_at,omitempty"`
+	UpdatedAt       *Timestamp `json:"updated_at,omitempty"`
+	Homepage        *string    `json:"homepage,omitempty"`
+	Size            *int       `json:"size,omitempty"`
+	StargazersCount *int       `json:"stargazers_count,omitempty"`
+	WatchersCount   *int       `json:"watchers_count,omitempty"`
+	Language        *string    `json:"language,omitempty"`
+	HasIssues       *bool      `json:"has_issues,omitempty"`
+	HasDownloads    *bool      `json:"has_downloads,omitempty"`
+	HasWiki         *bool      `json:"has_wiki,omitempty"`
+	HasPages        *bool      `json:"has_pages,omitempty"`
+	ForksCount      *int       `json:"forks_count,omitempty"`
+	OpenIssuesCount *int       `json:"open_issues_count,omitempty"`
+	DefaultBranch   *string    `json:"default_branch,omitempty"`
+	MasterBranch    *string    `json:"master_branch,omitempty"`
+	Organization    *string    `json:"organization,omitempty"`
+	URL             *string    `json:"url,omitempty"`
+	ArchiveURL      *string    `json:"archive_url,omitempty"`
+	HTMLURL         *string    `json:"html_url,omitempty"`
+	StatusesURL     *string    `json:"statuses_url,omitempty"`
+	GitURL          *string    `json:"git_url,omitempty"`
+	SSHURL          *string    `json:"ssh_url,omitempty"`
+	CloneURL        *string    `json:"clone_url,omitempty"`
+	SVNURL          *string    `json:"svn_url,omitempty"`
+}
+
+// PushEventRepoOwner is a basic representation of user/org in a PushEvent payload.
+type PushEventRepoOwner struct {
+	Name  *string `json:"name,omitempty"`
+	Email *string `json:"email,omitempty"`
+}
+
+// ReleaseEvent is triggered when a release is published.
+// The Webhook event name is "release".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#releaseevent
+type ReleaseEvent struct {
+	// Action is the action that was performed. Possible value is: "published".
+	Action  *string            `json:"action,omitempty"`
+	Release *RepositoryRelease `json:"release,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// RepositoryEvent is triggered when a repository is created.
+// The Webhook event name is "repository".
+//
+// Events of this type are not visible in timelines, they are only used to
+// trigger organization webhooks.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#repositoryevent
+type RepositoryEvent struct {
+	// Action is the action that was performed. Possible values are: "created", "deleted",
+	// "publicized", "privatized".
+	Action *string     `json:"action,omitempty"`
+	Repo   *Repository `json:"repository,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Org          *Organization `json:"organization,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// RepositoryVulnerabilityAlertEvent is triggered when a security alert is created, dismissed, or resolved.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#repositoryvulnerabilityalertevent
+type RepositoryVulnerabilityAlertEvent struct {
+	// Action is the action that was performed. This can be: "create", "dismiss", "resolve".
+	Action *string `json:"action,omitempty"`
+
+	//The security alert of the vulnerable dependency.
+	Alert *struct {
+		ID                  *int64     `json:"id,omitempty"`
+		AffectedRange       *string    `json:"affected_range,omitempty"`
+		AffectedPackageName *string    `json:"affected_package_name,omitempty"`
+		ExternalReference   *string    `json:"external_reference,omitempty"`
+		ExternalIdentifier  *string    `json:"external_identifier,omitempty"`
+		FixedIn             *string    `json:"fixed_in,omitempty"`
+		Dismisser           *User      `json:"dismisser,omitempty"`
+		DismissReason       *string    `json:"dismiss_reason,omitempty"`
+		DismissedAt         *Timestamp `json:"dismissed_at,omitempty"`
+	} `json:"alert,omitempty"`
+}
+
+// StatusEvent is triggered when the status of a Git commit changes.
+// The Webhook event name is "status".
+//
+// Events of this type are not visible in timelines, they are only used to
+// trigger hooks.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#statusevent
+type StatusEvent struct {
+	SHA *string `json:"sha,omitempty"`
+	// State is the new state. Possible values are: "pending", "success", "failure", "error".
+	State       *string   `json:"state,omitempty"`
+	Description *string   `json:"description,omitempty"`
+	TargetURL   *string   `json:"target_url,omitempty"`
+	Branches    []*Branch `json:"branches,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	ID           *int64            `json:"id,omitempty"`
+	Name         *string           `json:"name,omitempty"`
+	Context      *string           `json:"context,omitempty"`
+	Commit       *RepositoryCommit `json:"commit,omitempty"`
+	CreatedAt    *Timestamp        `json:"created_at,omitempty"`
+	UpdatedAt    *Timestamp        `json:"updated_at,omitempty"`
+	Repo         *Repository       `json:"repository,omitempty"`
+	Sender       *User             `json:"sender,omitempty"`
+	Installation *Installation     `json:"installation,omitempty"`
+}
+
+// TeamEvent is triggered when an organization's team is created, modified or deleted.
+// The Webhook event name is "team".
+//
+// Events of this type are not visible in timelines. These events are only used
+// to trigger hooks.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#teamevent
+type TeamEvent struct {
+	Action  *string     `json:"action,omitempty"`
+	Team    *Team       `json:"team,omitempty"`
+	Changes *TeamChange `json:"changes,omitempty"`
+	Repo    *Repository `json:"repository,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Org          *Organization `json:"organization,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// TeamAddEvent is triggered when a repository is added to a team.
+// The Webhook event name is "team_add".
+//
+// Events of this type are not visible in timelines. These events are only used
+// to trigger hooks.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#teamaddevent
+type TeamAddEvent struct {
+	Team *Team       `json:"team,omitempty"`
+	Repo *Repository `json:"repository,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Org          *Organization `json:"organization,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// WatchEvent is related to starring a repository, not watching. See this API
+// blog post for an explanation: https://developer.github.com/changes/2012-09-05-watcher-api/
+//
+// The event’s actor is the user who starred a repository, and the event’s
+// repository is the repository that was starred.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#watchevent
+type WatchEvent struct {
+	// Action is the action that was performed. Possible value is: "started".
+	Action *string `json:"action,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
diff --git a/vendor/github.com/google/go-github/v24/github/gen-accessors.go b/vendor/github.com/google/go-github/v24/github/gen-accessors.go
new file mode 100644
index 000000000..fe92206fc
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/gen-accessors.go
@@ -0,0 +1,332 @@
+// Copyright 2017 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+// gen-accessors generates accessor methods for structs with pointer fields.
+//
+// It is meant to be used by the go-github authors in conjunction with the
+// go generate tool before sending a commit to GitHub.
+package main
+
+import (
+	"bytes"
+	"flag"
+	"fmt"
+	"go/ast"
+	"go/format"
+	"go/parser"
+	"go/token"
+	"io/ioutil"
+	"log"
+	"os"
+	"sort"
+	"strings"
+	"text/template"
+)
+
+const (
+	fileSuffix = "-accessors.go"
+)
+
+var (
+	verbose = flag.Bool("v", false, "Print verbose log messages")
+
+	sourceTmpl = template.Must(template.New("source").Parse(source))
+
+	// blacklistStructMethod lists "struct.method" combos to skip.
+	blacklistStructMethod = map[string]bool{
+		"RepositoryContent.GetContent":    true,
+		"Client.GetBaseURL":               true,
+		"Client.GetUploadURL":             true,
+		"ErrorResponse.GetResponse":       true,
+		"RateLimitError.GetResponse":      true,
+		"AbuseRateLimitError.GetResponse": true,
+	}
+	// blacklistStruct lists structs to skip.
+	blacklistStruct = map[string]bool{
+		"Client": true,
+	}
+)
+
+func logf(fmt string, args ...interface{}) {
+	if *verbose {
+		log.Printf(fmt, args...)
+	}
+}
+
+func main() {
+	flag.Parse()
+	fset := token.NewFileSet()
+
+	pkgs, err := parser.ParseDir(fset, ".", sourceFilter, 0)
+	if err != nil {
+		log.Fatal(err)
+		return
+	}
+
+	for pkgName, pkg := range pkgs {
+		t := &templateData{
+			filename: pkgName + fileSuffix,
+			Year:     2017,
+			Package:  pkgName,
+			Imports:  map[string]string{},
+		}
+		for filename, f := range pkg.Files {
+			logf("Processing %v...", filename)
+			if err := t.processAST(f); err != nil {
+				log.Fatal(err)
+			}
+		}
+		if err := t.dump(); err != nil {
+			log.Fatal(err)
+		}
+	}
+	logf("Done.")
+}
+
+func (t *templateData) processAST(f *ast.File) error {
+	for _, decl := range f.Decls {
+		gd, ok := decl.(*ast.GenDecl)
+		if !ok {
+			continue
+		}
+		for _, spec := range gd.Specs {
+			ts, ok := spec.(*ast.TypeSpec)
+			if !ok {
+				continue
+			}
+			// Skip unexported identifiers.
+			if !ts.Name.IsExported() {
+				logf("Struct %v is unexported; skipping.", ts.Name)
+				continue
+			}
+			// Check if the struct is blacklisted.
+			if blacklistStruct[ts.Name.Name] {
+				logf("Struct %v is blacklisted; skipping.", ts.Name)
+				continue
+			}
+			st, ok := ts.Type.(*ast.StructType)
+			if !ok {
+				continue
+			}
+			for _, field := range st.Fields.List {
+				se, ok := field.Type.(*ast.StarExpr)
+				if len(field.Names) == 0 || !ok {
+					continue
+				}
+
+				fieldName := field.Names[0]
+				// Skip unexported identifiers.
+				if !fieldName.IsExported() {
+					logf("Field %v is unexported; skipping.", fieldName)
+					continue
+				}
+				// Check if "struct.method" is blacklisted.
+				if key := fmt.Sprintf("%v.Get%v", ts.Name, fieldName); blacklistStructMethod[key] {
+					logf("Method %v is blacklisted; skipping.", key)
+					continue
+				}
+
+				switch x := se.X.(type) {
+				case *ast.ArrayType:
+					t.addArrayType(x, ts.Name.String(), fieldName.String())
+				case *ast.Ident:
+					t.addIdent(x, ts.Name.String(), fieldName.String())
+				case *ast.MapType:
+					t.addMapType(x, ts.Name.String(), fieldName.String())
+				case *ast.SelectorExpr:
+					t.addSelectorExpr(x, ts.Name.String(), fieldName.String())
+				default:
+					logf("processAST: type %q, field %q, unknown %T: %+v", ts.Name, fieldName, x, x)
+				}
+			}
+		}
+	}
+	return nil
+}
+
+func sourceFilter(fi os.FileInfo) bool {
+	return !strings.HasSuffix(fi.Name(), "_test.go") && !strings.HasSuffix(fi.Name(), fileSuffix)
+}
+
+func (t *templateData) dump() error {
+	if len(t.Getters) == 0 {
+		logf("No getters for %v; skipping.", t.filename)
+		return nil
+	}
+
+	// Sort getters by ReceiverType.FieldName.
+	sort.Sort(byName(t.Getters))
+
+	var buf bytes.Buffer
+	if err := sourceTmpl.Execute(&buf, t); err != nil {
+		return err
+	}
+	clean, err := format.Source(buf.Bytes())
+	if err != nil {
+		return err
+	}
+
+	logf("Writing %v...", t.filename)
+	return ioutil.WriteFile(t.filename, clean, 0644)
+}
+
+func newGetter(receiverType, fieldName, fieldType, zeroValue string, namedStruct bool) *getter {
+	return &getter{
+		sortVal:      strings.ToLower(receiverType) + "." + strings.ToLower(fieldName),
+		ReceiverVar:  strings.ToLower(receiverType[:1]),
+		ReceiverType: receiverType,
+		FieldName:    fieldName,
+		FieldType:    fieldType,
+		ZeroValue:    zeroValue,
+		NamedStruct:  namedStruct,
+	}
+}
+
+func (t *templateData) addArrayType(x *ast.ArrayType, receiverType, fieldName string) {
+	var eltType string
+	switch elt := x.Elt.(type) {
+	case *ast.Ident:
+		eltType = elt.String()
+	default:
+		logf("addArrayType: type %q, field %q: unknown elt type: %T %+v; skipping.", receiverType, fieldName, elt, elt)
+		return
+	}
+
+	t.Getters = append(t.Getters, newGetter(receiverType, fieldName, "[]"+eltType, "nil", false))
+}
+
+func (t *templateData) addIdent(x *ast.Ident, receiverType, fieldName string) {
+	var zeroValue string
+	var namedStruct = false
+	switch x.String() {
+	case "int", "int64":
+		zeroValue = "0"
+	case "string":
+		zeroValue = `""`
+	case "bool":
+		zeroValue = "false"
+	case "Timestamp":
+		zeroValue = "Timestamp{}"
+	default:
+		zeroValue = "nil"
+		namedStruct = true
+	}
+
+	t.Getters = append(t.Getters, newGetter(receiverType, fieldName, x.String(), zeroValue, namedStruct))
+}
+
+func (t *templateData) addMapType(x *ast.MapType, receiverType, fieldName string) {
+	var keyType string
+	switch key := x.Key.(type) {
+	case *ast.Ident:
+		keyType = key.String()
+	default:
+		logf("addMapType: type %q, field %q: unknown key type: %T %+v; skipping.", receiverType, fieldName, key, key)
+		return
+	}
+
+	var valueType string
+	switch value := x.Value.(type) {
+	case *ast.Ident:
+		valueType = value.String()
+	default:
+		logf("addMapType: type %q, field %q: unknown value type: %T %+v; skipping.", receiverType, fieldName, value, value)
+		return
+	}
+
+	fieldType := fmt.Sprintf("map[%v]%v", keyType, valueType)
+	zeroValue := fmt.Sprintf("map[%v]%v{}", keyType, valueType)
+	t.Getters = append(t.Getters, newGetter(receiverType, fieldName, fieldType, zeroValue, false))
+}
+
+func (t *templateData) addSelectorExpr(x *ast.SelectorExpr, receiverType, fieldName string) {
+	if strings.ToLower(fieldName[:1]) == fieldName[:1] { // Non-exported field.
+		return
+	}
+
+	var xX string
+	if xx, ok := x.X.(*ast.Ident); ok {
+		xX = xx.String()
+	}
+
+	switch xX {
+	case "time", "json":
+		if xX == "json" {
+			t.Imports["encoding/json"] = "encoding/json"
+		} else {
+			t.Imports[xX] = xX
+		}
+		fieldType := fmt.Sprintf("%v.%v", xX, x.Sel.Name)
+		zeroValue := fmt.Sprintf("%v.%v{}", xX, x.Sel.Name)
+		if xX == "time" && x.Sel.Name == "Duration" {
+			zeroValue = "0"
+		}
+		t.Getters = append(t.Getters, newGetter(receiverType, fieldName, fieldType, zeroValue, false))
+	default:
+		logf("addSelectorExpr: xX %q, type %q, field %q: unknown x=%+v; skipping.", xX, receiverType, fieldName, x)
+	}
+}
+
+type templateData struct {
+	filename string
+	Year     int
+	Package  string
+	Imports  map[string]string
+	Getters  []*getter
+}
+
+type getter struct {
+	sortVal      string // Lower-case version of "ReceiverType.FieldName".
+	ReceiverVar  string // The one-letter variable name to match the ReceiverType.
+	ReceiverType string
+	FieldName    string
+	FieldType    string
+	ZeroValue    string
+	NamedStruct  bool // Getter for named struct.
+}
+
+type byName []*getter
+
+func (b byName) Len() int           { return len(b) }
+func (b byName) Less(i, j int) bool { return b[i].sortVal < b[j].sortVal }
+func (b byName) Swap(i, j int)      { b[i], b[j] = b[j], b[i] }
+
+const source = `// Copyright {{.Year}} The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Code generated by gen-accessors; DO NOT EDIT.
+
+package {{.Package}}
+{{with .Imports}}
+import (
+  {{- range . -}}
+  "{{.}}"
+  {{end -}}
+)
+{{end}}
+{{range .Getters}}
+{{if .NamedStruct}}
+// Get{{.FieldName}} returns the {{.FieldName}} field.
+func ({{.ReceiverVar}} *{{.ReceiverType}}) Get{{.FieldName}}() *{{.FieldType}} {
+  if {{.ReceiverVar}} == nil {
+    return {{.ZeroValue}}
+  }
+  return {{.ReceiverVar}}.{{.FieldName}}
+}
+{{else}}
+// Get{{.FieldName}} returns the {{.FieldName}} field if it's non-nil, zero value otherwise.
+func ({{.ReceiverVar}} *{{.ReceiverType}}) Get{{.FieldName}}() {{.FieldType}} {
+  if {{.ReceiverVar}} == nil || {{.ReceiverVar}}.{{.FieldName}} == nil {
+    return {{.ZeroValue}}
+  }
+  return *{{.ReceiverVar}}.{{.FieldName}}
+}
+{{end}}
+{{end}}
+`
diff --git a/vendor/github.com/google/go-github/v24/github/gists.go b/vendor/github.com/google/go-github/v24/github/gists.go
new file mode 100644
index 000000000..15e0bc2cd
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/gists.go
@@ -0,0 +1,358 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// GistsService handles communication with the Gist related
+// methods of the GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/
+type GistsService service
+
+// Gist represents a GitHub's gist.
+type Gist struct {
+	ID          *string                   `json:"id,omitempty"`
+	Description *string                   `json:"description,omitempty"`
+	Public      *bool                     `json:"public,omitempty"`
+	Owner       *User                     `json:"owner,omitempty"`
+	Files       map[GistFilename]GistFile `json:"files,omitempty"`
+	Comments    *int                      `json:"comments,omitempty"`
+	HTMLURL     *string                   `json:"html_url,omitempty"`
+	GitPullURL  *string                   `json:"git_pull_url,omitempty"`
+	GitPushURL  *string                   `json:"git_push_url,omitempty"`
+	CreatedAt   *time.Time                `json:"created_at,omitempty"`
+	UpdatedAt   *time.Time                `json:"updated_at,omitempty"`
+	NodeID      *string                   `json:"node_id,omitempty"`
+}
+
+func (g Gist) String() string {
+	return Stringify(g)
+}
+
+// GistFilename represents filename on a gist.
+type GistFilename string
+
+// GistFile represents a file on a gist.
+type GistFile struct {
+	Size     *int    `json:"size,omitempty"`
+	Filename *string `json:"filename,omitempty"`
+	Language *string `json:"language,omitempty"`
+	Type     *string `json:"type,omitempty"`
+	RawURL   *string `json:"raw_url,omitempty"`
+	Content  *string `json:"content,omitempty"`
+}
+
+func (g GistFile) String() string {
+	return Stringify(g)
+}
+
+// GistCommit represents a commit on a gist.
+type GistCommit struct {
+	URL          *string      `json:"url,omitempty"`
+	Version      *string      `json:"version,omitempty"`
+	User         *User        `json:"user,omitempty"`
+	ChangeStatus *CommitStats `json:"change_status,omitempty"`
+	CommittedAt  *Timestamp   `json:"committed_at,omitempty"`
+	NodeID       *string      `json:"node_id,omitempty"`
+}
+
+func (gc GistCommit) String() string {
+	return Stringify(gc)
+}
+
+// GistFork represents a fork of a gist.
+type GistFork struct {
+	URL       *string    `json:"url,omitempty"`
+	User      *User      `json:"user,omitempty"`
+	ID        *string    `json:"id,omitempty"`
+	CreatedAt *Timestamp `json:"created_at,omitempty"`
+	UpdatedAt *Timestamp `json:"updated_at,omitempty"`
+	NodeID    *string    `json:"node_id,omitempty"`
+}
+
+func (gf GistFork) String() string {
+	return Stringify(gf)
+}
+
+// GistListOptions specifies the optional parameters to the
+// GistsService.List, GistsService.ListAll, and GistsService.ListStarred methods.
+type GistListOptions struct {
+	// Since filters Gists by time.
+	Since time.Time `url:"since,omitempty"`
+
+	ListOptions
+}
+
+// List gists for a user. Passing the empty string will list
+// all public gists if called anonymously. However, if the call
+// is authenticated, it will returns all gists for the authenticated
+// user.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#list-gists
+func (s *GistsService) List(ctx context.Context, user string, opt *GistListOptions) ([]*Gist, *Response, error) {
+	var u string
+	if user != "" {
+		u = fmt.Sprintf("users/%v/gists", user)
+	} else {
+		u = "gists"
+	}
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var gists []*Gist
+	resp, err := s.client.Do(ctx, req, &gists)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return gists, resp, nil
+}
+
+// ListAll lists all public gists.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#list-gists
+func (s *GistsService) ListAll(ctx context.Context, opt *GistListOptions) ([]*Gist, *Response, error) {
+	u, err := addOptions("gists/public", opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var gists []*Gist
+	resp, err := s.client.Do(ctx, req, &gists)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return gists, resp, nil
+}
+
+// ListStarred lists starred gists of authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#list-gists
+func (s *GistsService) ListStarred(ctx context.Context, opt *GistListOptions) ([]*Gist, *Response, error) {
+	u, err := addOptions("gists/starred", opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var gists []*Gist
+	resp, err := s.client.Do(ctx, req, &gists)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return gists, resp, nil
+}
+
+// Get a single gist.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#get-a-single-gist
+func (s *GistsService) Get(ctx context.Context, id string) (*Gist, *Response, error) {
+	u := fmt.Sprintf("gists/%v", id)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	gist := new(Gist)
+	resp, err := s.client.Do(ctx, req, gist)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return gist, resp, nil
+}
+
+// GetRevision gets a specific revision of a gist.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#get-a-specific-revision-of-a-gist
+func (s *GistsService) GetRevision(ctx context.Context, id, sha string) (*Gist, *Response, error) {
+	u := fmt.Sprintf("gists/%v/%v", id, sha)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	gist := new(Gist)
+	resp, err := s.client.Do(ctx, req, gist)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return gist, resp, nil
+}
+
+// Create a gist for authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#create-a-gist
+func (s *GistsService) Create(ctx context.Context, gist *Gist) (*Gist, *Response, error) {
+	u := "gists"
+	req, err := s.client.NewRequest("POST", u, gist)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	g := new(Gist)
+	resp, err := s.client.Do(ctx, req, g)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return g, resp, nil
+}
+
+// Edit a gist.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#edit-a-gist
+func (s *GistsService) Edit(ctx context.Context, id string, gist *Gist) (*Gist, *Response, error) {
+	u := fmt.Sprintf("gists/%v", id)
+	req, err := s.client.NewRequest("PATCH", u, gist)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	g := new(Gist)
+	resp, err := s.client.Do(ctx, req, g)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return g, resp, nil
+}
+
+// ListCommits lists commits of a gist.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#list-gist-commits
+func (s *GistsService) ListCommits(ctx context.Context, id string, opt *ListOptions) ([]*GistCommit, *Response, error) {
+	u := fmt.Sprintf("gists/%v/commits", id)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var gistCommits []*GistCommit
+	resp, err := s.client.Do(ctx, req, &gistCommits)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return gistCommits, resp, nil
+}
+
+// Delete a gist.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#delete-a-gist
+func (s *GistsService) Delete(ctx context.Context, id string) (*Response, error) {
+	u := fmt.Sprintf("gists/%v", id)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
+
+// Star a gist on behalf of authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#star-a-gist
+func (s *GistsService) Star(ctx context.Context, id string) (*Response, error) {
+	u := fmt.Sprintf("gists/%v/star", id)
+	req, err := s.client.NewRequest("PUT", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
+
+// Unstar a gist on a behalf of authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#unstar-a-gist
+func (s *GistsService) Unstar(ctx context.Context, id string) (*Response, error) {
+	u := fmt.Sprintf("gists/%v/star", id)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
+
+// IsStarred checks if a gist is starred by authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#check-if-a-gist-is-starred
+func (s *GistsService) IsStarred(ctx context.Context, id string) (bool, *Response, error) {
+	u := fmt.Sprintf("gists/%v/star", id)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return false, nil, err
+	}
+	resp, err := s.client.Do(ctx, req, nil)
+	starred, err := parseBoolResponse(err)
+	return starred, resp, err
+}
+
+// Fork a gist.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#fork-a-gist
+func (s *GistsService) Fork(ctx context.Context, id string) (*Gist, *Response, error) {
+	u := fmt.Sprintf("gists/%v/forks", id)
+	req, err := s.client.NewRequest("POST", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	g := new(Gist)
+	resp, err := s.client.Do(ctx, req, g)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return g, resp, nil
+}
+
+// ListForks lists forks of a gist.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#list-gist-forks
+func (s *GistsService) ListForks(ctx context.Context, id string) ([]*GistFork, *Response, error) {
+	u := fmt.Sprintf("gists/%v/forks", id)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var gistForks []*GistFork
+	resp, err := s.client.Do(ctx, req, &gistForks)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return gistForks, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/gists_comments.go b/vendor/github.com/google/go-github/v24/github/gists_comments.go
new file mode 100644
index 000000000..d5322e3d8
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/gists_comments.go
@@ -0,0 +1,119 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// GistComment represents a Gist comment.
+type GistComment struct {
+	ID        *int64     `json:"id,omitempty"`
+	URL       *string    `json:"url,omitempty"`
+	Body      *string    `json:"body,omitempty"`
+	User      *User      `json:"user,omitempty"`
+	CreatedAt *time.Time `json:"created_at,omitempty"`
+}
+
+func (g GistComment) String() string {
+	return Stringify(g)
+}
+
+// ListComments lists all comments for a gist.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/comments/#list-comments-on-a-gist
+func (s *GistsService) ListComments(ctx context.Context, gistID string, opt *ListOptions) ([]*GistComment, *Response, error) {
+	u := fmt.Sprintf("gists/%v/comments", gistID)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var comments []*GistComment
+	resp, err := s.client.Do(ctx, req, &comments)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return comments, resp, nil
+}
+
+// GetComment retrieves a single comment from a gist.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/comments/#get-a-single-comment
+func (s *GistsService) GetComment(ctx context.Context, gistID string, commentID int64) (*GistComment, *Response, error) {
+	u := fmt.Sprintf("gists/%v/comments/%v", gistID, commentID)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	c := new(GistComment)
+	resp, err := s.client.Do(ctx, req, c)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return c, resp, nil
+}
+
+// CreateComment creates a comment for a gist.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/comments/#create-a-comment
+func (s *GistsService) CreateComment(ctx context.Context, gistID string, comment *GistComment) (*GistComment, *Response, error) {
+	u := fmt.Sprintf("gists/%v/comments", gistID)
+	req, err := s.client.NewRequest("POST", u, comment)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	c := new(GistComment)
+	resp, err := s.client.Do(ctx, req, c)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return c, resp, nil
+}
+
+// EditComment edits an existing gist comment.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/comments/#edit-a-comment
+func (s *GistsService) EditComment(ctx context.Context, gistID string, commentID int64, comment *GistComment) (*GistComment, *Response, error) {
+	u := fmt.Sprintf("gists/%v/comments/%v", gistID, commentID)
+	req, err := s.client.NewRequest("PATCH", u, comment)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	c := new(GistComment)
+	resp, err := s.client.Do(ctx, req, c)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return c, resp, nil
+}
+
+// DeleteComment deletes a gist comment.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/comments/#delete-a-comment
+func (s *GistsService) DeleteComment(ctx context.Context, gistID string, commentID int64) (*Response, error) {
+	u := fmt.Sprintf("gists/%v/comments/%v", gistID, commentID)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/git.go b/vendor/github.com/google/go-github/v24/github/git.go
new file mode 100644
index 000000000..1ce47437b
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/git.go
@@ -0,0 +1,12 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+// GitService handles communication with the git data related
+// methods of the GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/git/
+type GitService service
diff --git a/vendor/github.com/google/go-github/v24/github/git_blobs.go b/vendor/github.com/google/go-github/v24/github/git_blobs.go
new file mode 100644
index 000000000..70aee14a7
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/git_blobs.go
@@ -0,0 +1,69 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+)
+
+// Blob represents a blob object.
+type Blob struct {
+	Content  *string `json:"content,omitempty"`
+	Encoding *string `json:"encoding,omitempty"`
+	SHA      *string `json:"sha,omitempty"`
+	Size     *int    `json:"size,omitempty"`
+	URL      *string `json:"url,omitempty"`
+	NodeID   *string `json:"node_id,omitempty"`
+}
+
+// GetBlob fetches a blob from a repo given a SHA.
+//
+// GitHub API docs: https://developer.github.com/v3/git/blobs/#get-a-blob
+func (s *GitService) GetBlob(ctx context.Context, owner string, repo string, sha string) (*Blob, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/git/blobs/%v", owner, repo, sha)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	blob := new(Blob)
+	resp, err := s.client.Do(ctx, req, blob)
+	return blob, resp, err
+}
+
+// GetBlobRaw fetches a blob's contents from a repo.
+// Unlike GetBlob, it returns the raw bytes rather than the base64-encoded data.
+//
+// GitHub API docs: https://developer.github.com/v3/git/blobs/#get-a-blob
+func (s *GitService) GetBlobRaw(ctx context.Context, owner, repo, sha string) ([]byte, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/git/blobs/%v", owner, repo, sha)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+	req.Header.Set("Accept", "application/vnd.github.v3.raw")
+
+	var buf bytes.Buffer
+	resp, err := s.client.Do(ctx, req, &buf)
+	return buf.Bytes(), resp, err
+}
+
+// CreateBlob creates a blob object.
+//
+// GitHub API docs: https://developer.github.com/v3/git/blobs/#create-a-blob
+func (s *GitService) CreateBlob(ctx context.Context, owner string, repo string, blob *Blob) (*Blob, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/git/blobs", owner, repo)
+	req, err := s.client.NewRequest("POST", u, blob)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	t := new(Blob)
+	resp, err := s.client.Do(ctx, req, t)
+	return t, resp, err
+}
diff --git a/vendor/github.com/google/go-github/v24/github/git_commits.go b/vendor/github.com/google/go-github/v24/github/git_commits.go
new file mode 100644
index 000000000..9dfd3afb3
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/git_commits.go
@@ -0,0 +1,135 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// SignatureVerification represents GPG signature verification.
+type SignatureVerification struct {
+	Verified  *bool   `json:"verified,omitempty"`
+	Reason    *string `json:"reason,omitempty"`
+	Signature *string `json:"signature,omitempty"`
+	Payload   *string `json:"payload,omitempty"`
+}
+
+// Commit represents a GitHub commit.
+type Commit struct {
+	SHA          *string                `json:"sha,omitempty"`
+	Author       *CommitAuthor          `json:"author,omitempty"`
+	Committer    *CommitAuthor          `json:"committer,omitempty"`
+	Message      *string                `json:"message,omitempty"`
+	Tree         *Tree                  `json:"tree,omitempty"`
+	Parents      []Commit               `json:"parents,omitempty"`
+	Stats        *CommitStats           `json:"stats,omitempty"`
+	HTMLURL      *string                `json:"html_url,omitempty"`
+	URL          *string                `json:"url,omitempty"`
+	Verification *SignatureVerification `json:"verification,omitempty"`
+	NodeID       *string                `json:"node_id,omitempty"`
+
+	// CommentCount is the number of GitHub comments on the commit. This
+	// is only populated for requests that fetch GitHub data like
+	// Pulls.ListCommits, Repositories.ListCommits, etc.
+	CommentCount *int `json:"comment_count,omitempty"`
+}
+
+func (c Commit) String() string {
+	return Stringify(c)
+}
+
+// CommitAuthor represents the author or committer of a commit. The commit
+// author may not correspond to a GitHub User.
+type CommitAuthor struct {
+	Date  *time.Time `json:"date,omitempty"`
+	Name  *string    `json:"name,omitempty"`
+	Email *string    `json:"email,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Login *string `json:"username,omitempty"` // Renamed for go-github consistency.
+}
+
+func (c CommitAuthor) String() string {
+	return Stringify(c)
+}
+
+// GetCommit fetches the Commit object for a given SHA.
+//
+// GitHub API docs: https://developer.github.com/v3/git/commits/#get-a-commit
+func (s *GitService) GetCommit(ctx context.Context, owner string, repo string, sha string) (*Commit, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/git/commits/%v", owner, repo, sha)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	c := new(Commit)
+	resp, err := s.client.Do(ctx, req, c)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return c, resp, nil
+}
+
+// createCommit represents the body of a CreateCommit request.
+type createCommit struct {
+	Author    *CommitAuthor `json:"author,omitempty"`
+	Committer *CommitAuthor `json:"committer,omitempty"`
+	Message   *string       `json:"message,omitempty"`
+	Tree      *string       `json:"tree,omitempty"`
+	Parents   []string      `json:"parents,omitempty"`
+	Signature *string       `json:"signature,omitempty"`
+}
+
+// CreateCommit creates a new commit in a repository.
+// commit must not be nil.
+//
+// The commit.Committer is optional and will be filled with the commit.Author
+// data if omitted. If the commit.Author is omitted, it will be filled in with
+// the authenticated user’s information and the current date.
+//
+// GitHub API docs: https://developer.github.com/v3/git/commits/#create-a-commit
+func (s *GitService) CreateCommit(ctx context.Context, owner string, repo string, commit *Commit) (*Commit, *Response, error) {
+	if commit == nil {
+		return nil, nil, fmt.Errorf("commit must be provided")
+	}
+
+	u := fmt.Sprintf("repos/%v/%v/git/commits", owner, repo)
+
+	parents := make([]string, len(commit.Parents))
+	for i, parent := range commit.Parents {
+		parents[i] = *parent.SHA
+	}
+
+	body := &createCommit{
+		Author:    commit.Author,
+		Committer: commit.Committer,
+		Message:   commit.Message,
+		Parents:   parents,
+	}
+	if commit.Tree != nil {
+		body.Tree = commit.Tree.SHA
+	}
+	if commit.Verification != nil {
+		body.Signature = commit.Verification.Signature
+	}
+
+	req, err := s.client.NewRequest("POST", u, body)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	c := new(Commit)
+	resp, err := s.client.Do(ctx, req, c)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return c, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/git_refs.go b/vendor/github.com/google/go-github/v24/github/git_refs.go
new file mode 100644
index 000000000..3f381d5f2
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/git_refs.go
@@ -0,0 +1,219 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"net/url"
+	"strings"
+)
+
+// Reference represents a GitHub reference.
+type Reference struct {
+	Ref    *string    `json:"ref"`
+	URL    *string    `json:"url"`
+	Object *GitObject `json:"object"`
+	NodeID *string    `json:"node_id,omitempty"`
+}
+
+func (r Reference) String() string {
+	return Stringify(r)
+}
+
+// GitObject represents a Git object.
+type GitObject struct {
+	Type *string `json:"type"`
+	SHA  *string `json:"sha"`
+	URL  *string `json:"url"`
+}
+
+func (o GitObject) String() string {
+	return Stringify(o)
+}
+
+// createRefRequest represents the payload for creating a reference.
+type createRefRequest struct {
+	Ref *string `json:"ref"`
+	SHA *string `json:"sha"`
+}
+
+// updateRefRequest represents the payload for updating a reference.
+type updateRefRequest struct {
+	SHA   *string `json:"sha"`
+	Force *bool   `json:"force"`
+}
+
+// GetRef fetches a single Reference object for a given Git ref.
+// If there is no exact match, GetRef will return an error.
+//
+// Note: The GitHub API can return multiple matches.
+// If you wish to use this functionality please use the GetRefs() method.
+//
+// GitHub API docs: https://developer.github.com/v3/git/refs/#get-a-reference
+func (s *GitService) GetRef(ctx context.Context, owner string, repo string, ref string) (*Reference, *Response, error) {
+	ref = strings.TrimPrefix(ref, "refs/")
+	u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, url.QueryEscape(ref))
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	r := new(Reference)
+	resp, err := s.client.Do(ctx, req, r)
+	if _, ok := err.(*json.UnmarshalTypeError); ok {
+		// Multiple refs, means there wasn't an exact match.
+		return nil, resp, errors.New("no exact match found for this ref")
+	} else if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
+
+// GetRefs fetches a slice of Reference objects for a given Git ref.
+// If there is an exact match, only that ref is returned.
+// If there is no exact match, GitHub returns all refs that start with ref.
+// If returned error is nil, there will be at least 1 ref returned.
+// For example:
+//
+// 	"heads/featureA" -> ["refs/heads/featureA"]                         // Exact match, single ref is returned.
+// 	"heads/feature"  -> ["refs/heads/featureA", "refs/heads/featureB"]  // All refs that start with ref.
+// 	"heads/notexist" -> []                                              // Returns an error.
+//
+// GitHub API docs: https://developer.github.com/v3/git/refs/#get-a-reference
+func (s *GitService) GetRefs(ctx context.Context, owner string, repo string, ref string) ([]*Reference, *Response, error) {
+	ref = strings.TrimPrefix(ref, "refs/")
+	u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, url.QueryEscape(ref))
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var rawJSON json.RawMessage
+	resp, err := s.client.Do(ctx, req, &rawJSON)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	// Prioritize the most common case: a single returned ref.
+	r := new(Reference)
+	singleUnmarshalError := json.Unmarshal(rawJSON, r)
+	if singleUnmarshalError == nil {
+		return []*Reference{r}, resp, nil
+	}
+
+	// Attempt to unmarshal multiple refs.
+	var rs []*Reference
+	multipleUnmarshalError := json.Unmarshal(rawJSON, &rs)
+	if multipleUnmarshalError == nil {
+		if len(rs) == 0 {
+			return nil, resp, fmt.Errorf("unexpected response from GitHub API: an array of refs with length 0")
+		}
+		return rs, resp, nil
+	}
+
+	return nil, resp, fmt.Errorf("unmarshalling failed for both single and multiple refs: %s and %s", singleUnmarshalError, multipleUnmarshalError)
+}
+
+// ReferenceListOptions specifies optional parameters to the
+// GitService.ListRefs method.
+type ReferenceListOptions struct {
+	Type string `url:"-"`
+
+	ListOptions
+}
+
+// ListRefs lists all refs in a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/git/refs/#get-all-references
+func (s *GitService) ListRefs(ctx context.Context, owner, repo string, opt *ReferenceListOptions) ([]*Reference, *Response, error) {
+	var u string
+	if opt != nil && opt.Type != "" {
+		u = fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, opt.Type)
+	} else {
+		u = fmt.Sprintf("repos/%v/%v/git/refs", owner, repo)
+	}
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var rs []*Reference
+	resp, err := s.client.Do(ctx, req, &rs)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return rs, resp, nil
+}
+
+// CreateRef creates a new ref in a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/git/refs/#create-a-reference
+func (s *GitService) CreateRef(ctx context.Context, owner string, repo string, ref *Reference) (*Reference, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/git/refs", owner, repo)
+	req, err := s.client.NewRequest("POST", u, &createRefRequest{
+		// back-compat with previous behavior that didn't require 'refs/' prefix
+		Ref: String("refs/" + strings.TrimPrefix(*ref.Ref, "refs/")),
+		SHA: ref.Object.SHA,
+	})
+	if err != nil {
+		return nil, nil, err
+	}
+
+	r := new(Reference)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
+
+// UpdateRef updates an existing ref in a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/git/refs/#update-a-reference
+func (s *GitService) UpdateRef(ctx context.Context, owner string, repo string, ref *Reference, force bool) (*Reference, *Response, error) {
+	refPath := strings.TrimPrefix(*ref.Ref, "refs/")
+	u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, refPath)
+	req, err := s.client.NewRequest("PATCH", u, &updateRefRequest{
+		SHA:   ref.Object.SHA,
+		Force: &force,
+	})
+	if err != nil {
+		return nil, nil, err
+	}
+
+	r := new(Reference)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
+
+// DeleteRef deletes a ref from a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/git/refs/#delete-a-reference
+func (s *GitService) DeleteRef(ctx context.Context, owner string, repo string, ref string) (*Response, error) {
+	ref = strings.TrimPrefix(ref, "refs/")
+	u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, url.QueryEscape(ref))
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/git_tags.go b/vendor/github.com/google/go-github/v24/github/git_tags.go
new file mode 100644
index 000000000..abdbde682
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/git_tags.go
@@ -0,0 +1,76 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// Tag represents a tag object.
+type Tag struct {
+	Tag          *string                `json:"tag,omitempty"`
+	SHA          *string                `json:"sha,omitempty"`
+	URL          *string                `json:"url,omitempty"`
+	Message      *string                `json:"message,omitempty"`
+	Tagger       *CommitAuthor          `json:"tagger,omitempty"`
+	Object       *GitObject             `json:"object,omitempty"`
+	Verification *SignatureVerification `json:"verification,omitempty"`
+	NodeID       *string                `json:"node_id,omitempty"`
+}
+
+// createTagRequest represents the body of a CreateTag request. This is mostly
+// identical to Tag with the exception that the object SHA and Type are
+// top-level fields, rather than being nested inside a JSON object.
+type createTagRequest struct {
+	Tag     *string       `json:"tag,omitempty"`
+	Message *string       `json:"message,omitempty"`
+	Object  *string       `json:"object,omitempty"`
+	Type    *string       `json:"type,omitempty"`
+	Tagger  *CommitAuthor `json:"tagger,omitempty"`
+}
+
+// GetTag fetches a tag from a repo given a SHA.
+//
+// GitHub API docs: https://developer.github.com/v3/git/tags/#get-a-tag
+func (s *GitService) GetTag(ctx context.Context, owner string, repo string, sha string) (*Tag, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/git/tags/%v", owner, repo, sha)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	tag := new(Tag)
+	resp, err := s.client.Do(ctx, req, tag)
+	return tag, resp, err
+}
+
+// CreateTag creates a tag object.
+//
+// GitHub API docs: https://developer.github.com/v3/git/tags/#create-a-tag-object
+func (s *GitService) CreateTag(ctx context.Context, owner string, repo string, tag *Tag) (*Tag, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/git/tags", owner, repo)
+
+	// convert Tag into a createTagRequest
+	tagRequest := &createTagRequest{
+		Tag:     tag.Tag,
+		Message: tag.Message,
+		Tagger:  tag.Tagger,
+	}
+	if tag.Object != nil {
+		tagRequest.Object = tag.Object.SHA
+		tagRequest.Type = tag.Object.Type
+	}
+
+	req, err := s.client.NewRequest("POST", u, tagRequest)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	t := new(Tag)
+	resp, err := s.client.Do(ctx, req, t)
+	return t, resp, err
+}
diff --git a/vendor/github.com/google/go-github/v24/github/git_trees.go b/vendor/github.com/google/go-github/v24/github/git_trees.go
new file mode 100644
index 000000000..4bc291354
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/git_trees.go
@@ -0,0 +1,99 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// Tree represents a GitHub tree.
+type Tree struct {
+	SHA     *string     `json:"sha,omitempty"`
+	Entries []TreeEntry `json:"tree,omitempty"`
+
+	// Truncated is true if the number of items in the tree
+	// exceeded GitHub's maximum limit and the Entries were truncated
+	// in the response. Only populated for requests that fetch
+	// trees like Git.GetTree.
+	Truncated *bool `json:"truncated,omitempty"`
+}
+
+func (t Tree) String() string {
+	return Stringify(t)
+}
+
+// TreeEntry represents the contents of a tree structure. TreeEntry can
+// represent either a blob, a commit (in the case of a submodule), or another
+// tree.
+type TreeEntry struct {
+	SHA     *string `json:"sha,omitempty"`
+	Path    *string `json:"path,omitempty"`
+	Mode    *string `json:"mode,omitempty"`
+	Type    *string `json:"type,omitempty"`
+	Size    *int    `json:"size,omitempty"`
+	Content *string `json:"content,omitempty"`
+	URL     *string `json:"url,omitempty"`
+}
+
+func (t TreeEntry) String() string {
+	return Stringify(t)
+}
+
+// GetTree fetches the Tree object for a given sha hash from a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/git/trees/#get-a-tree
+func (s *GitService) GetTree(ctx context.Context, owner string, repo string, sha string, recursive bool) (*Tree, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/git/trees/%v", owner, repo, sha)
+	if recursive {
+		u += "?recursive=1"
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	t := new(Tree)
+	resp, err := s.client.Do(ctx, req, t)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return t, resp, nil
+}
+
+// createTree represents the body of a CreateTree request.
+type createTree struct {
+	BaseTree string      `json:"base_tree,omitempty"`
+	Entries  []TreeEntry `json:"tree"`
+}
+
+// CreateTree creates a new tree in a repository. If both a tree and a nested
+// path modifying that tree are specified, it will overwrite the contents of
+// that tree with the new path contents and write a new tree out.
+//
+// GitHub API docs: https://developer.github.com/v3/git/trees/#create-a-tree
+func (s *GitService) CreateTree(ctx context.Context, owner string, repo string, baseTree string, entries []TreeEntry) (*Tree, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/git/trees", owner, repo)
+
+	body := &createTree{
+		BaseTree: baseTree,
+		Entries:  entries,
+	}
+	req, err := s.client.NewRequest("POST", u, body)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	t := new(Tree)
+	resp, err := s.client.Do(ctx, req, t)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return t, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/github-accessors.go b/vendor/github.com/google/go-github/v24/github/github-accessors.go
new file mode 100644
index 000000000..b9deb7e1c
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/github-accessors.go
@@ -0,0 +1,12413 @@
+// Copyright 2017 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Code generated by gen-accessors; DO NOT EDIT.
+
+package github
+
+import (
+	"encoding/json"
+	"time"
+)
+
+// GetRetryAfter returns the RetryAfter field if it's non-nil, zero value otherwise.
+func (a *AbuseRateLimitError) GetRetryAfter() time.Duration {
+	if a == nil || a.RetryAfter == nil {
+		return 0
+	}
+	return *a.RetryAfter
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (a *AdminEnforcement) GetURL() string {
+	if a == nil || a.URL == nil {
+		return ""
+	}
+	return *a.URL
+}
+
+// GetComments returns the Comments field.
+func (a *AdminStats) GetComments() *CommentStats {
+	if a == nil {
+		return nil
+	}
+	return a.Comments
+}
+
+// GetGists returns the Gists field.
+func (a *AdminStats) GetGists() *GistStats {
+	if a == nil {
+		return nil
+	}
+	return a.Gists
+}
+
+// GetHooks returns the Hooks field.
+func (a *AdminStats) GetHooks() *HookStats {
+	if a == nil {
+		return nil
+	}
+	return a.Hooks
+}
+
+// GetIssues returns the Issues field.
+func (a *AdminStats) GetIssues() *IssueStats {
+	if a == nil {
+		return nil
+	}
+	return a.Issues
+}
+
+// GetMilestones returns the Milestones field.
+func (a *AdminStats) GetMilestones() *MilestoneStats {
+	if a == nil {
+		return nil
+	}
+	return a.Milestones
+}
+
+// GetOrgs returns the Orgs field.
+func (a *AdminStats) GetOrgs() *OrgStats {
+	if a == nil {
+		return nil
+	}
+	return a.Orgs
+}
+
+// GetPages returns the Pages field.
+func (a *AdminStats) GetPages() *PageStats {
+	if a == nil {
+		return nil
+	}
+	return a.Pages
+}
+
+// GetPulls returns the Pulls field.
+func (a *AdminStats) GetPulls() *PullStats {
+	if a == nil {
+		return nil
+	}
+	return a.Pulls
+}
+
+// GetRepos returns the Repos field.
+func (a *AdminStats) GetRepos() *RepoStats {
+	if a == nil {
+		return nil
+	}
+	return a.Repos
+}
+
+// GetUsers returns the Users field.
+func (a *AdminStats) GetUsers() *UserStats {
+	if a == nil {
+		return nil
+	}
+	return a.Users
+}
+
+// GetVerifiablePasswordAuthentication returns the VerifiablePasswordAuthentication field if it's non-nil, zero value otherwise.
+func (a *APIMeta) GetVerifiablePasswordAuthentication() bool {
+	if a == nil || a.VerifiablePasswordAuthentication == nil {
+		return false
+	}
+	return *a.VerifiablePasswordAuthentication
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (a *App) GetCreatedAt() time.Time {
+	if a == nil || a.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *a.CreatedAt
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (a *App) GetDescription() string {
+	if a == nil || a.Description == nil {
+		return ""
+	}
+	return *a.Description
+}
+
+// GetExternalURL returns the ExternalURL field if it's non-nil, zero value otherwise.
+func (a *App) GetExternalURL() string {
+	if a == nil || a.ExternalURL == nil {
+		return ""
+	}
+	return *a.ExternalURL
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (a *App) GetHTMLURL() string {
+	if a == nil || a.HTMLURL == nil {
+		return ""
+	}
+	return *a.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (a *App) GetID() int64 {
+	if a == nil || a.ID == nil {
+		return 0
+	}
+	return *a.ID
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (a *App) GetName() string {
+	if a == nil || a.Name == nil {
+		return ""
+	}
+	return *a.Name
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (a *App) GetNodeID() string {
+	if a == nil || a.NodeID == nil {
+		return ""
+	}
+	return *a.NodeID
+}
+
+// GetOwner returns the Owner field.
+func (a *App) GetOwner() *User {
+	if a == nil {
+		return nil
+	}
+	return a.Owner
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (a *App) GetUpdatedAt() time.Time {
+	if a == nil || a.UpdatedAt == nil {
+		return time.Time{}
+	}
+	return *a.UpdatedAt
+}
+
+// GetApp returns the App field.
+func (a *Authorization) GetApp() *AuthorizationApp {
+	if a == nil {
+		return nil
+	}
+	return a.App
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (a *Authorization) GetCreatedAt() Timestamp {
+	if a == nil || a.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *a.CreatedAt
+}
+
+// GetFingerprint returns the Fingerprint field if it's non-nil, zero value otherwise.
+func (a *Authorization) GetFingerprint() string {
+	if a == nil || a.Fingerprint == nil {
+		return ""
+	}
+	return *a.Fingerprint
+}
+
+// GetHashedToken returns the HashedToken field if it's non-nil, zero value otherwise.
+func (a *Authorization) GetHashedToken() string {
+	if a == nil || a.HashedToken == nil {
+		return ""
+	}
+	return *a.HashedToken
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (a *Authorization) GetID() int64 {
+	if a == nil || a.ID == nil {
+		return 0
+	}
+	return *a.ID
+}
+
+// GetNote returns the Note field if it's non-nil, zero value otherwise.
+func (a *Authorization) GetNote() string {
+	if a == nil || a.Note == nil {
+		return ""
+	}
+	return *a.Note
+}
+
+// GetNoteURL returns the NoteURL field if it's non-nil, zero value otherwise.
+func (a *Authorization) GetNoteURL() string {
+	if a == nil || a.NoteURL == nil {
+		return ""
+	}
+	return *a.NoteURL
+}
+
+// GetToken returns the Token field if it's non-nil, zero value otherwise.
+func (a *Authorization) GetToken() string {
+	if a == nil || a.Token == nil {
+		return ""
+	}
+	return *a.Token
+}
+
+// GetTokenLastEight returns the TokenLastEight field if it's non-nil, zero value otherwise.
+func (a *Authorization) GetTokenLastEight() string {
+	if a == nil || a.TokenLastEight == nil {
+		return ""
+	}
+	return *a.TokenLastEight
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (a *Authorization) GetUpdatedAt() Timestamp {
+	if a == nil || a.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *a.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (a *Authorization) GetURL() string {
+	if a == nil || a.URL == nil {
+		return ""
+	}
+	return *a.URL
+}
+
+// GetUser returns the User field.
+func (a *Authorization) GetUser() *User {
+	if a == nil {
+		return nil
+	}
+	return a.User
+}
+
+// GetClientID returns the ClientID field if it's non-nil, zero value otherwise.
+func (a *AuthorizationApp) GetClientID() string {
+	if a == nil || a.ClientID == nil {
+		return ""
+	}
+	return *a.ClientID
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (a *AuthorizationApp) GetName() string {
+	if a == nil || a.Name == nil {
+		return ""
+	}
+	return *a.Name
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (a *AuthorizationApp) GetURL() string {
+	if a == nil || a.URL == nil {
+		return ""
+	}
+	return *a.URL
+}
+
+// GetClientID returns the ClientID field if it's non-nil, zero value otherwise.
+func (a *AuthorizationRequest) GetClientID() string {
+	if a == nil || a.ClientID == nil {
+		return ""
+	}
+	return *a.ClientID
+}
+
+// GetClientSecret returns the ClientSecret field if it's non-nil, zero value otherwise.
+func (a *AuthorizationRequest) GetClientSecret() string {
+	if a == nil || a.ClientSecret == nil {
+		return ""
+	}
+	return *a.ClientSecret
+}
+
+// GetFingerprint returns the Fingerprint field if it's non-nil, zero value otherwise.
+func (a *AuthorizationRequest) GetFingerprint() string {
+	if a == nil || a.Fingerprint == nil {
+		return ""
+	}
+	return *a.Fingerprint
+}
+
+// GetNote returns the Note field if it's non-nil, zero value otherwise.
+func (a *AuthorizationRequest) GetNote() string {
+	if a == nil || a.Note == nil {
+		return ""
+	}
+	return *a.Note
+}
+
+// GetNoteURL returns the NoteURL field if it's non-nil, zero value otherwise.
+func (a *AuthorizationRequest) GetNoteURL() string {
+	if a == nil || a.NoteURL == nil {
+		return ""
+	}
+	return *a.NoteURL
+}
+
+// GetFingerprint returns the Fingerprint field if it's non-nil, zero value otherwise.
+func (a *AuthorizationUpdateRequest) GetFingerprint() string {
+	if a == nil || a.Fingerprint == nil {
+		return ""
+	}
+	return *a.Fingerprint
+}
+
+// GetNote returns the Note field if it's non-nil, zero value otherwise.
+func (a *AuthorizationUpdateRequest) GetNote() string {
+	if a == nil || a.Note == nil {
+		return ""
+	}
+	return *a.Note
+}
+
+// GetNoteURL returns the NoteURL field if it's non-nil, zero value otherwise.
+func (a *AuthorizationUpdateRequest) GetNoteURL() string {
+	if a == nil || a.NoteURL == nil {
+		return ""
+	}
+	return *a.NoteURL
+}
+
+// GetAppID returns the AppID field if it's non-nil, zero value otherwise.
+func (a *AutoTriggerCheck) GetAppID() int64 {
+	if a == nil || a.AppID == nil {
+		return 0
+	}
+	return *a.AppID
+}
+
+// GetSetting returns the Setting field if it's non-nil, zero value otherwise.
+func (a *AutoTriggerCheck) GetSetting() bool {
+	if a == nil || a.Setting == nil {
+		return false
+	}
+	return *a.Setting
+}
+
+// GetContent returns the Content field if it's non-nil, zero value otherwise.
+func (b *Blob) GetContent() string {
+	if b == nil || b.Content == nil {
+		return ""
+	}
+	return *b.Content
+}
+
+// GetEncoding returns the Encoding field if it's non-nil, zero value otherwise.
+func (b *Blob) GetEncoding() string {
+	if b == nil || b.Encoding == nil {
+		return ""
+	}
+	return *b.Encoding
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (b *Blob) GetNodeID() string {
+	if b == nil || b.NodeID == nil {
+		return ""
+	}
+	return *b.NodeID
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (b *Blob) GetSHA() string {
+	if b == nil || b.SHA == nil {
+		return ""
+	}
+	return *b.SHA
+}
+
+// GetSize returns the Size field if it's non-nil, zero value otherwise.
+func (b *Blob) GetSize() int {
+	if b == nil || b.Size == nil {
+		return 0
+	}
+	return *b.Size
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (b *Blob) GetURL() string {
+	if b == nil || b.URL == nil {
+		return ""
+	}
+	return *b.URL
+}
+
+// GetCommit returns the Commit field.
+func (b *Branch) GetCommit() *RepositoryCommit {
+	if b == nil {
+		return nil
+	}
+	return b.Commit
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (b *Branch) GetName() string {
+	if b == nil || b.Name == nil {
+		return ""
+	}
+	return *b.Name
+}
+
+// GetProtected returns the Protected field if it's non-nil, zero value otherwise.
+func (b *Branch) GetProtected() bool {
+	if b == nil || b.Protected == nil {
+		return false
+	}
+	return *b.Protected
+}
+
+// GetApp returns the App field.
+func (c *CheckRun) GetApp() *App {
+	if c == nil {
+		return nil
+	}
+	return c.App
+}
+
+// GetCheckSuite returns the CheckSuite field.
+func (c *CheckRun) GetCheckSuite() *CheckSuite {
+	if c == nil {
+		return nil
+	}
+	return c.CheckSuite
+}
+
+// GetCompletedAt returns the CompletedAt field if it's non-nil, zero value otherwise.
+func (c *CheckRun) GetCompletedAt() Timestamp {
+	if c == nil || c.CompletedAt == nil {
+		return Timestamp{}
+	}
+	return *c.CompletedAt
+}
+
+// GetConclusion returns the Conclusion field if it's non-nil, zero value otherwise.
+func (c *CheckRun) GetConclusion() string {
+	if c == nil || c.Conclusion == nil {
+		return ""
+	}
+	return *c.Conclusion
+}
+
+// GetDetailsURL returns the DetailsURL field if it's non-nil, zero value otherwise.
+func (c *CheckRun) GetDetailsURL() string {
+	if c == nil || c.DetailsURL == nil {
+		return ""
+	}
+	return *c.DetailsURL
+}
+
+// GetExternalID returns the ExternalID field if it's non-nil, zero value otherwise.
+func (c *CheckRun) GetExternalID() string {
+	if c == nil || c.ExternalID == nil {
+		return ""
+	}
+	return *c.ExternalID
+}
+
+// GetHeadSHA returns the HeadSHA field if it's non-nil, zero value otherwise.
+func (c *CheckRun) GetHeadSHA() string {
+	if c == nil || c.HeadSHA == nil {
+		return ""
+	}
+	return *c.HeadSHA
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (c *CheckRun) GetHTMLURL() string {
+	if c == nil || c.HTMLURL == nil {
+		return ""
+	}
+	return *c.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (c *CheckRun) GetID() int64 {
+	if c == nil || c.ID == nil {
+		return 0
+	}
+	return *c.ID
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (c *CheckRun) GetName() string {
+	if c == nil || c.Name == nil {
+		return ""
+	}
+	return *c.Name
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (c *CheckRun) GetNodeID() string {
+	if c == nil || c.NodeID == nil {
+		return ""
+	}
+	return *c.NodeID
+}
+
+// GetOutput returns the Output field.
+func (c *CheckRun) GetOutput() *CheckRunOutput {
+	if c == nil {
+		return nil
+	}
+	return c.Output
+}
+
+// GetStartedAt returns the StartedAt field if it's non-nil, zero value otherwise.
+func (c *CheckRun) GetStartedAt() Timestamp {
+	if c == nil || c.StartedAt == nil {
+		return Timestamp{}
+	}
+	return *c.StartedAt
+}
+
+// GetStatus returns the Status field if it's non-nil, zero value otherwise.
+func (c *CheckRun) GetStatus() string {
+	if c == nil || c.Status == nil {
+		return ""
+	}
+	return *c.Status
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (c *CheckRun) GetURL() string {
+	if c == nil || c.URL == nil {
+		return ""
+	}
+	return *c.URL
+}
+
+// GetAnnotationLevel returns the AnnotationLevel field if it's non-nil, zero value otherwise.
+func (c *CheckRunAnnotation) GetAnnotationLevel() string {
+	if c == nil || c.AnnotationLevel == nil {
+		return ""
+	}
+	return *c.AnnotationLevel
+}
+
+// GetBlobHRef returns the BlobHRef field if it's non-nil, zero value otherwise.
+func (c *CheckRunAnnotation) GetBlobHRef() string {
+	if c == nil || c.BlobHRef == nil {
+		return ""
+	}
+	return *c.BlobHRef
+}
+
+// GetEndLine returns the EndLine field if it's non-nil, zero value otherwise.
+func (c *CheckRunAnnotation) GetEndLine() int {
+	if c == nil || c.EndLine == nil {
+		return 0
+	}
+	return *c.EndLine
+}
+
+// GetMessage returns the Message field if it's non-nil, zero value otherwise.
+func (c *CheckRunAnnotation) GetMessage() string {
+	if c == nil || c.Message == nil {
+		return ""
+	}
+	return *c.Message
+}
+
+// GetPath returns the Path field if it's non-nil, zero value otherwise.
+func (c *CheckRunAnnotation) GetPath() string {
+	if c == nil || c.Path == nil {
+		return ""
+	}
+	return *c.Path
+}
+
+// GetRawDetails returns the RawDetails field if it's non-nil, zero value otherwise.
+func (c *CheckRunAnnotation) GetRawDetails() string {
+	if c == nil || c.RawDetails == nil {
+		return ""
+	}
+	return *c.RawDetails
+}
+
+// GetStartLine returns the StartLine field if it's non-nil, zero value otherwise.
+func (c *CheckRunAnnotation) GetStartLine() int {
+	if c == nil || c.StartLine == nil {
+		return 0
+	}
+	return *c.StartLine
+}
+
+// GetTitle returns the Title field if it's non-nil, zero value otherwise.
+func (c *CheckRunAnnotation) GetTitle() string {
+	if c == nil || c.Title == nil {
+		return ""
+	}
+	return *c.Title
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (c *CheckRunEvent) GetAction() string {
+	if c == nil || c.Action == nil {
+		return ""
+	}
+	return *c.Action
+}
+
+// GetCheckRun returns the CheckRun field.
+func (c *CheckRunEvent) GetCheckRun() *CheckRun {
+	if c == nil {
+		return nil
+	}
+	return c.CheckRun
+}
+
+// GetInstallation returns the Installation field.
+func (c *CheckRunEvent) GetInstallation() *Installation {
+	if c == nil {
+		return nil
+	}
+	return c.Installation
+}
+
+// GetOrg returns the Org field.
+func (c *CheckRunEvent) GetOrg() *Organization {
+	if c == nil {
+		return nil
+	}
+	return c.Org
+}
+
+// GetRepo returns the Repo field.
+func (c *CheckRunEvent) GetRepo() *Repository {
+	if c == nil {
+		return nil
+	}
+	return c.Repo
+}
+
+// GetRequestedAction returns the RequestedAction field.
+func (c *CheckRunEvent) GetRequestedAction() *RequestedAction {
+	if c == nil {
+		return nil
+	}
+	return c.RequestedAction
+}
+
+// GetSender returns the Sender field.
+func (c *CheckRunEvent) GetSender() *User {
+	if c == nil {
+		return nil
+	}
+	return c.Sender
+}
+
+// GetAlt returns the Alt field if it's non-nil, zero value otherwise.
+func (c *CheckRunImage) GetAlt() string {
+	if c == nil || c.Alt == nil {
+		return ""
+	}
+	return *c.Alt
+}
+
+// GetCaption returns the Caption field if it's non-nil, zero value otherwise.
+func (c *CheckRunImage) GetCaption() string {
+	if c == nil || c.Caption == nil {
+		return ""
+	}
+	return *c.Caption
+}
+
+// GetImageURL returns the ImageURL field if it's non-nil, zero value otherwise.
+func (c *CheckRunImage) GetImageURL() string {
+	if c == nil || c.ImageURL == nil {
+		return ""
+	}
+	return *c.ImageURL
+}
+
+// GetAnnotationsCount returns the AnnotationsCount field if it's non-nil, zero value otherwise.
+func (c *CheckRunOutput) GetAnnotationsCount() int {
+	if c == nil || c.AnnotationsCount == nil {
+		return 0
+	}
+	return *c.AnnotationsCount
+}
+
+// GetAnnotationsURL returns the AnnotationsURL field if it's non-nil, zero value otherwise.
+func (c *CheckRunOutput) GetAnnotationsURL() string {
+	if c == nil || c.AnnotationsURL == nil {
+		return ""
+	}
+	return *c.AnnotationsURL
+}
+
+// GetSummary returns the Summary field if it's non-nil, zero value otherwise.
+func (c *CheckRunOutput) GetSummary() string {
+	if c == nil || c.Summary == nil {
+		return ""
+	}
+	return *c.Summary
+}
+
+// GetText returns the Text field if it's non-nil, zero value otherwise.
+func (c *CheckRunOutput) GetText() string {
+	if c == nil || c.Text == nil {
+		return ""
+	}
+	return *c.Text
+}
+
+// GetTitle returns the Title field if it's non-nil, zero value otherwise.
+func (c *CheckRunOutput) GetTitle() string {
+	if c == nil || c.Title == nil {
+		return ""
+	}
+	return *c.Title
+}
+
+// GetAfterSHA returns the AfterSHA field if it's non-nil, zero value otherwise.
+func (c *CheckSuite) GetAfterSHA() string {
+	if c == nil || c.AfterSHA == nil {
+		return ""
+	}
+	return *c.AfterSHA
+}
+
+// GetApp returns the App field.
+func (c *CheckSuite) GetApp() *App {
+	if c == nil {
+		return nil
+	}
+	return c.App
+}
+
+// GetBeforeSHA returns the BeforeSHA field if it's non-nil, zero value otherwise.
+func (c *CheckSuite) GetBeforeSHA() string {
+	if c == nil || c.BeforeSHA == nil {
+		return ""
+	}
+	return *c.BeforeSHA
+}
+
+// GetConclusion returns the Conclusion field if it's non-nil, zero value otherwise.
+func (c *CheckSuite) GetConclusion() string {
+	if c == nil || c.Conclusion == nil {
+		return ""
+	}
+	return *c.Conclusion
+}
+
+// GetHeadBranch returns the HeadBranch field if it's non-nil, zero value otherwise.
+func (c *CheckSuite) GetHeadBranch() string {
+	if c == nil || c.HeadBranch == nil {
+		return ""
+	}
+	return *c.HeadBranch
+}
+
+// GetHeadSHA returns the HeadSHA field if it's non-nil, zero value otherwise.
+func (c *CheckSuite) GetHeadSHA() string {
+	if c == nil || c.HeadSHA == nil {
+		return ""
+	}
+	return *c.HeadSHA
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (c *CheckSuite) GetID() int64 {
+	if c == nil || c.ID == nil {
+		return 0
+	}
+	return *c.ID
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (c *CheckSuite) GetNodeID() string {
+	if c == nil || c.NodeID == nil {
+		return ""
+	}
+	return *c.NodeID
+}
+
+// GetRepository returns the Repository field.
+func (c *CheckSuite) GetRepository() *Repository {
+	if c == nil {
+		return nil
+	}
+	return c.Repository
+}
+
+// GetStatus returns the Status field if it's non-nil, zero value otherwise.
+func (c *CheckSuite) GetStatus() string {
+	if c == nil || c.Status == nil {
+		return ""
+	}
+	return *c.Status
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (c *CheckSuite) GetURL() string {
+	if c == nil || c.URL == nil {
+		return ""
+	}
+	return *c.URL
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (c *CheckSuiteEvent) GetAction() string {
+	if c == nil || c.Action == nil {
+		return ""
+	}
+	return *c.Action
+}
+
+// GetCheckSuite returns the CheckSuite field.
+func (c *CheckSuiteEvent) GetCheckSuite() *CheckSuite {
+	if c == nil {
+		return nil
+	}
+	return c.CheckSuite
+}
+
+// GetInstallation returns the Installation field.
+func (c *CheckSuiteEvent) GetInstallation() *Installation {
+	if c == nil {
+		return nil
+	}
+	return c.Installation
+}
+
+// GetOrg returns the Org field.
+func (c *CheckSuiteEvent) GetOrg() *Organization {
+	if c == nil {
+		return nil
+	}
+	return c.Org
+}
+
+// GetRepo returns the Repo field.
+func (c *CheckSuiteEvent) GetRepo() *Repository {
+	if c == nil {
+		return nil
+	}
+	return c.Repo
+}
+
+// GetSender returns the Sender field.
+func (c *CheckSuiteEvent) GetSender() *User {
+	if c == nil {
+		return nil
+	}
+	return c.Sender
+}
+
+// GetPreferenceList returns the PreferenceList field.
+func (c *CheckSuitePreferenceOptions) GetPreferenceList() *PreferenceList {
+	if c == nil {
+		return nil
+	}
+	return c.PreferenceList
+}
+
+// GetPreferences returns the Preferences field.
+func (c *CheckSuitePreferenceResults) GetPreferences() *PreferenceList {
+	if c == nil {
+		return nil
+	}
+	return c.Preferences
+}
+
+// GetRepository returns the Repository field.
+func (c *CheckSuitePreferenceResults) GetRepository() *Repository {
+	if c == nil {
+		return nil
+	}
+	return c.Repository
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (c *CodeOfConduct) GetBody() string {
+	if c == nil || c.Body == nil {
+		return ""
+	}
+	return *c.Body
+}
+
+// GetKey returns the Key field if it's non-nil, zero value otherwise.
+func (c *CodeOfConduct) GetKey() string {
+	if c == nil || c.Key == nil {
+		return ""
+	}
+	return *c.Key
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (c *CodeOfConduct) GetName() string {
+	if c == nil || c.Name == nil {
+		return ""
+	}
+	return *c.Name
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (c *CodeOfConduct) GetURL() string {
+	if c == nil || c.URL == nil {
+		return ""
+	}
+	return *c.URL
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (c *CodeResult) GetHTMLURL() string {
+	if c == nil || c.HTMLURL == nil {
+		return ""
+	}
+	return *c.HTMLURL
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (c *CodeResult) GetName() string {
+	if c == nil || c.Name == nil {
+		return ""
+	}
+	return *c.Name
+}
+
+// GetPath returns the Path field if it's non-nil, zero value otherwise.
+func (c *CodeResult) GetPath() string {
+	if c == nil || c.Path == nil {
+		return ""
+	}
+	return *c.Path
+}
+
+// GetRepository returns the Repository field.
+func (c *CodeResult) GetRepository() *Repository {
+	if c == nil {
+		return nil
+	}
+	return c.Repository
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (c *CodeResult) GetSHA() string {
+	if c == nil || c.SHA == nil {
+		return ""
+	}
+	return *c.SHA
+}
+
+// GetIncompleteResults returns the IncompleteResults field if it's non-nil, zero value otherwise.
+func (c *CodeSearchResult) GetIncompleteResults() bool {
+	if c == nil || c.IncompleteResults == nil {
+		return false
+	}
+	return *c.IncompleteResults
+}
+
+// GetTotal returns the Total field if it's non-nil, zero value otherwise.
+func (c *CodeSearchResult) GetTotal() int {
+	if c == nil || c.Total == nil {
+		return 0
+	}
+	return *c.Total
+}
+
+// GetCommitURL returns the CommitURL field if it's non-nil, zero value otherwise.
+func (c *CombinedStatus) GetCommitURL() string {
+	if c == nil || c.CommitURL == nil {
+		return ""
+	}
+	return *c.CommitURL
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (c *CombinedStatus) GetName() string {
+	if c == nil || c.Name == nil {
+		return ""
+	}
+	return *c.Name
+}
+
+// GetRepositoryURL returns the RepositoryURL field if it's non-nil, zero value otherwise.
+func (c *CombinedStatus) GetRepositoryURL() string {
+	if c == nil || c.RepositoryURL == nil {
+		return ""
+	}
+	return *c.RepositoryURL
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (c *CombinedStatus) GetSHA() string {
+	if c == nil || c.SHA == nil {
+		return ""
+	}
+	return *c.SHA
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (c *CombinedStatus) GetState() string {
+	if c == nil || c.State == nil {
+		return ""
+	}
+	return *c.State
+}
+
+// GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise.
+func (c *CombinedStatus) GetTotalCount() int {
+	if c == nil || c.TotalCount == nil {
+		return 0
+	}
+	return *c.TotalCount
+}
+
+// GetTotalCommitComments returns the TotalCommitComments field if it's non-nil, zero value otherwise.
+func (c *CommentStats) GetTotalCommitComments() int {
+	if c == nil || c.TotalCommitComments == nil {
+		return 0
+	}
+	return *c.TotalCommitComments
+}
+
+// GetTotalGistComments returns the TotalGistComments field if it's non-nil, zero value otherwise.
+func (c *CommentStats) GetTotalGistComments() int {
+	if c == nil || c.TotalGistComments == nil {
+		return 0
+	}
+	return *c.TotalGistComments
+}
+
+// GetTotalIssueComments returns the TotalIssueComments field if it's non-nil, zero value otherwise.
+func (c *CommentStats) GetTotalIssueComments() int {
+	if c == nil || c.TotalIssueComments == nil {
+		return 0
+	}
+	return *c.TotalIssueComments
+}
+
+// GetTotalPullRequestComments returns the TotalPullRequestComments field if it's non-nil, zero value otherwise.
+func (c *CommentStats) GetTotalPullRequestComments() int {
+	if c == nil || c.TotalPullRequestComments == nil {
+		return 0
+	}
+	return *c.TotalPullRequestComments
+}
+
+// GetAuthor returns the Author field.
+func (c *Commit) GetAuthor() *CommitAuthor {
+	if c == nil {
+		return nil
+	}
+	return c.Author
+}
+
+// GetCommentCount returns the CommentCount field if it's non-nil, zero value otherwise.
+func (c *Commit) GetCommentCount() int {
+	if c == nil || c.CommentCount == nil {
+		return 0
+	}
+	return *c.CommentCount
+}
+
+// GetCommitter returns the Committer field.
+func (c *Commit) GetCommitter() *CommitAuthor {
+	if c == nil {
+		return nil
+	}
+	return c.Committer
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (c *Commit) GetHTMLURL() string {
+	if c == nil || c.HTMLURL == nil {
+		return ""
+	}
+	return *c.HTMLURL
+}
+
+// GetMessage returns the Message field if it's non-nil, zero value otherwise.
+func (c *Commit) GetMessage() string {
+	if c == nil || c.Message == nil {
+		return ""
+	}
+	return *c.Message
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (c *Commit) GetNodeID() string {
+	if c == nil || c.NodeID == nil {
+		return ""
+	}
+	return *c.NodeID
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (c *Commit) GetSHA() string {
+	if c == nil || c.SHA == nil {
+		return ""
+	}
+	return *c.SHA
+}
+
+// GetStats returns the Stats field.
+func (c *Commit) GetStats() *CommitStats {
+	if c == nil {
+		return nil
+	}
+	return c.Stats
+}
+
+// GetTree returns the Tree field.
+func (c *Commit) GetTree() *Tree {
+	if c == nil {
+		return nil
+	}
+	return c.Tree
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (c *Commit) GetURL() string {
+	if c == nil || c.URL == nil {
+		return ""
+	}
+	return *c.URL
+}
+
+// GetVerification returns the Verification field.
+func (c *Commit) GetVerification() *SignatureVerification {
+	if c == nil {
+		return nil
+	}
+	return c.Verification
+}
+
+// GetDate returns the Date field if it's non-nil, zero value otherwise.
+func (c *CommitAuthor) GetDate() time.Time {
+	if c == nil || c.Date == nil {
+		return time.Time{}
+	}
+	return *c.Date
+}
+
+// GetEmail returns the Email field if it's non-nil, zero value otherwise.
+func (c *CommitAuthor) GetEmail() string {
+	if c == nil || c.Email == nil {
+		return ""
+	}
+	return *c.Email
+}
+
+// GetLogin returns the Login field if it's non-nil, zero value otherwise.
+func (c *CommitAuthor) GetLogin() string {
+	if c == nil || c.Login == nil {
+		return ""
+	}
+	return *c.Login
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (c *CommitAuthor) GetName() string {
+	if c == nil || c.Name == nil {
+		return ""
+	}
+	return *c.Name
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (c *CommitCommentEvent) GetAction() string {
+	if c == nil || c.Action == nil {
+		return ""
+	}
+	return *c.Action
+}
+
+// GetComment returns the Comment field.
+func (c *CommitCommentEvent) GetComment() *RepositoryComment {
+	if c == nil {
+		return nil
+	}
+	return c.Comment
+}
+
+// GetInstallation returns the Installation field.
+func (c *CommitCommentEvent) GetInstallation() *Installation {
+	if c == nil {
+		return nil
+	}
+	return c.Installation
+}
+
+// GetRepo returns the Repo field.
+func (c *CommitCommentEvent) GetRepo() *Repository {
+	if c == nil {
+		return nil
+	}
+	return c.Repo
+}
+
+// GetSender returns the Sender field.
+func (c *CommitCommentEvent) GetSender() *User {
+	if c == nil {
+		return nil
+	}
+	return c.Sender
+}
+
+// GetAdditions returns the Additions field if it's non-nil, zero value otherwise.
+func (c *CommitFile) GetAdditions() int {
+	if c == nil || c.Additions == nil {
+		return 0
+	}
+	return *c.Additions
+}
+
+// GetBlobURL returns the BlobURL field if it's non-nil, zero value otherwise.
+func (c *CommitFile) GetBlobURL() string {
+	if c == nil || c.BlobURL == nil {
+		return ""
+	}
+	return *c.BlobURL
+}
+
+// GetChanges returns the Changes field if it's non-nil, zero value otherwise.
+func (c *CommitFile) GetChanges() int {
+	if c == nil || c.Changes == nil {
+		return 0
+	}
+	return *c.Changes
+}
+
+// GetContentsURL returns the ContentsURL field if it's non-nil, zero value otherwise.
+func (c *CommitFile) GetContentsURL() string {
+	if c == nil || c.ContentsURL == nil {
+		return ""
+	}
+	return *c.ContentsURL
+}
+
+// GetDeletions returns the Deletions field if it's non-nil, zero value otherwise.
+func (c *CommitFile) GetDeletions() int {
+	if c == nil || c.Deletions == nil {
+		return 0
+	}
+	return *c.Deletions
+}
+
+// GetFilename returns the Filename field if it's non-nil, zero value otherwise.
+func (c *CommitFile) GetFilename() string {
+	if c == nil || c.Filename == nil {
+		return ""
+	}
+	return *c.Filename
+}
+
+// GetPatch returns the Patch field if it's non-nil, zero value otherwise.
+func (c *CommitFile) GetPatch() string {
+	if c == nil || c.Patch == nil {
+		return ""
+	}
+	return *c.Patch
+}
+
+// GetPreviousFilename returns the PreviousFilename field if it's non-nil, zero value otherwise.
+func (c *CommitFile) GetPreviousFilename() string {
+	if c == nil || c.PreviousFilename == nil {
+		return ""
+	}
+	return *c.PreviousFilename
+}
+
+// GetRawURL returns the RawURL field if it's non-nil, zero value otherwise.
+func (c *CommitFile) GetRawURL() string {
+	if c == nil || c.RawURL == nil {
+		return ""
+	}
+	return *c.RawURL
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (c *CommitFile) GetSHA() string {
+	if c == nil || c.SHA == nil {
+		return ""
+	}
+	return *c.SHA
+}
+
+// GetStatus returns the Status field if it's non-nil, zero value otherwise.
+func (c *CommitFile) GetStatus() string {
+	if c == nil || c.Status == nil {
+		return ""
+	}
+	return *c.Status
+}
+
+// GetAuthor returns the Author field.
+func (c *CommitResult) GetAuthor() *User {
+	if c == nil {
+		return nil
+	}
+	return c.Author
+}
+
+// GetCommentsURL returns the CommentsURL field if it's non-nil, zero value otherwise.
+func (c *CommitResult) GetCommentsURL() string {
+	if c == nil || c.CommentsURL == nil {
+		return ""
+	}
+	return *c.CommentsURL
+}
+
+// GetCommit returns the Commit field.
+func (c *CommitResult) GetCommit() *Commit {
+	if c == nil {
+		return nil
+	}
+	return c.Commit
+}
+
+// GetCommitter returns the Committer field.
+func (c *CommitResult) GetCommitter() *User {
+	if c == nil {
+		return nil
+	}
+	return c.Committer
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (c *CommitResult) GetHTMLURL() string {
+	if c == nil || c.HTMLURL == nil {
+		return ""
+	}
+	return *c.HTMLURL
+}
+
+// GetRepository returns the Repository field.
+func (c *CommitResult) GetRepository() *Repository {
+	if c == nil {
+		return nil
+	}
+	return c.Repository
+}
+
+// GetScore returns the Score field.
+func (c *CommitResult) GetScore() *float64 {
+	if c == nil {
+		return nil
+	}
+	return c.Score
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (c *CommitResult) GetSHA() string {
+	if c == nil || c.SHA == nil {
+		return ""
+	}
+	return *c.SHA
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (c *CommitResult) GetURL() string {
+	if c == nil || c.URL == nil {
+		return ""
+	}
+	return *c.URL
+}
+
+// GetAheadBy returns the AheadBy field if it's non-nil, zero value otherwise.
+func (c *CommitsComparison) GetAheadBy() int {
+	if c == nil || c.AheadBy == nil {
+		return 0
+	}
+	return *c.AheadBy
+}
+
+// GetBaseCommit returns the BaseCommit field.
+func (c *CommitsComparison) GetBaseCommit() *RepositoryCommit {
+	if c == nil {
+		return nil
+	}
+	return c.BaseCommit
+}
+
+// GetBehindBy returns the BehindBy field if it's non-nil, zero value otherwise.
+func (c *CommitsComparison) GetBehindBy() int {
+	if c == nil || c.BehindBy == nil {
+		return 0
+	}
+	return *c.BehindBy
+}
+
+// GetDiffURL returns the DiffURL field if it's non-nil, zero value otherwise.
+func (c *CommitsComparison) GetDiffURL() string {
+	if c == nil || c.DiffURL == nil {
+		return ""
+	}
+	return *c.DiffURL
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (c *CommitsComparison) GetHTMLURL() string {
+	if c == nil || c.HTMLURL == nil {
+		return ""
+	}
+	return *c.HTMLURL
+}
+
+// GetMergeBaseCommit returns the MergeBaseCommit field.
+func (c *CommitsComparison) GetMergeBaseCommit() *RepositoryCommit {
+	if c == nil {
+		return nil
+	}
+	return c.MergeBaseCommit
+}
+
+// GetPatchURL returns the PatchURL field if it's non-nil, zero value otherwise.
+func (c *CommitsComparison) GetPatchURL() string {
+	if c == nil || c.PatchURL == nil {
+		return ""
+	}
+	return *c.PatchURL
+}
+
+// GetPermalinkURL returns the PermalinkURL field if it's non-nil, zero value otherwise.
+func (c *CommitsComparison) GetPermalinkURL() string {
+	if c == nil || c.PermalinkURL == nil {
+		return ""
+	}
+	return *c.PermalinkURL
+}
+
+// GetStatus returns the Status field if it's non-nil, zero value otherwise.
+func (c *CommitsComparison) GetStatus() string {
+	if c == nil || c.Status == nil {
+		return ""
+	}
+	return *c.Status
+}
+
+// GetTotalCommits returns the TotalCommits field if it's non-nil, zero value otherwise.
+func (c *CommitsComparison) GetTotalCommits() int {
+	if c == nil || c.TotalCommits == nil {
+		return 0
+	}
+	return *c.TotalCommits
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (c *CommitsComparison) GetURL() string {
+	if c == nil || c.URL == nil {
+		return ""
+	}
+	return *c.URL
+}
+
+// GetIncompleteResults returns the IncompleteResults field if it's non-nil, zero value otherwise.
+func (c *CommitsSearchResult) GetIncompleteResults() bool {
+	if c == nil || c.IncompleteResults == nil {
+		return false
+	}
+	return *c.IncompleteResults
+}
+
+// GetTotal returns the Total field if it's non-nil, zero value otherwise.
+func (c *CommitsSearchResult) GetTotal() int {
+	if c == nil || c.Total == nil {
+		return 0
+	}
+	return *c.Total
+}
+
+// GetAdditions returns the Additions field if it's non-nil, zero value otherwise.
+func (c *CommitStats) GetAdditions() int {
+	if c == nil || c.Additions == nil {
+		return 0
+	}
+	return *c.Additions
+}
+
+// GetDeletions returns the Deletions field if it's non-nil, zero value otherwise.
+func (c *CommitStats) GetDeletions() int {
+	if c == nil || c.Deletions == nil {
+		return 0
+	}
+	return *c.Deletions
+}
+
+// GetTotal returns the Total field if it's non-nil, zero value otherwise.
+func (c *CommitStats) GetTotal() int {
+	if c == nil || c.Total == nil {
+		return 0
+	}
+	return *c.Total
+}
+
+// GetCodeOfConduct returns the CodeOfConduct field.
+func (c *CommunityHealthFiles) GetCodeOfConduct() *Metric {
+	if c == nil {
+		return nil
+	}
+	return c.CodeOfConduct
+}
+
+// GetContributing returns the Contributing field.
+func (c *CommunityHealthFiles) GetContributing() *Metric {
+	if c == nil {
+		return nil
+	}
+	return c.Contributing
+}
+
+// GetIssueTemplate returns the IssueTemplate field.
+func (c *CommunityHealthFiles) GetIssueTemplate() *Metric {
+	if c == nil {
+		return nil
+	}
+	return c.IssueTemplate
+}
+
+// GetLicense returns the License field.
+func (c *CommunityHealthFiles) GetLicense() *Metric {
+	if c == nil {
+		return nil
+	}
+	return c.License
+}
+
+// GetPullRequestTemplate returns the PullRequestTemplate field.
+func (c *CommunityHealthFiles) GetPullRequestTemplate() *Metric {
+	if c == nil {
+		return nil
+	}
+	return c.PullRequestTemplate
+}
+
+// GetReadme returns the Readme field.
+func (c *CommunityHealthFiles) GetReadme() *Metric {
+	if c == nil {
+		return nil
+	}
+	return c.Readme
+}
+
+// GetFiles returns the Files field.
+func (c *CommunityHealthMetrics) GetFiles() *CommunityHealthFiles {
+	if c == nil {
+		return nil
+	}
+	return c.Files
+}
+
+// GetHealthPercentage returns the HealthPercentage field if it's non-nil, zero value otherwise.
+func (c *CommunityHealthMetrics) GetHealthPercentage() int {
+	if c == nil || c.HealthPercentage == nil {
+		return 0
+	}
+	return *c.HealthPercentage
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (c *CommunityHealthMetrics) GetUpdatedAt() time.Time {
+	if c == nil || c.UpdatedAt == nil {
+		return time.Time{}
+	}
+	return *c.UpdatedAt
+}
+
+// GetAvatarURL returns the AvatarURL field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetAvatarURL() string {
+	if c == nil || c.AvatarURL == nil {
+		return ""
+	}
+	return *c.AvatarURL
+}
+
+// GetContributions returns the Contributions field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetContributions() int {
+	if c == nil || c.Contributions == nil {
+		return 0
+	}
+	return *c.Contributions
+}
+
+// GetEventsURL returns the EventsURL field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetEventsURL() string {
+	if c == nil || c.EventsURL == nil {
+		return ""
+	}
+	return *c.EventsURL
+}
+
+// GetFollowersURL returns the FollowersURL field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetFollowersURL() string {
+	if c == nil || c.FollowersURL == nil {
+		return ""
+	}
+	return *c.FollowersURL
+}
+
+// GetFollowingURL returns the FollowingURL field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetFollowingURL() string {
+	if c == nil || c.FollowingURL == nil {
+		return ""
+	}
+	return *c.FollowingURL
+}
+
+// GetGistsURL returns the GistsURL field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetGistsURL() string {
+	if c == nil || c.GistsURL == nil {
+		return ""
+	}
+	return *c.GistsURL
+}
+
+// GetGravatarID returns the GravatarID field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetGravatarID() string {
+	if c == nil || c.GravatarID == nil {
+		return ""
+	}
+	return *c.GravatarID
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetHTMLURL() string {
+	if c == nil || c.HTMLURL == nil {
+		return ""
+	}
+	return *c.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetID() int64 {
+	if c == nil || c.ID == nil {
+		return 0
+	}
+	return *c.ID
+}
+
+// GetLogin returns the Login field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetLogin() string {
+	if c == nil || c.Login == nil {
+		return ""
+	}
+	return *c.Login
+}
+
+// GetOrganizationsURL returns the OrganizationsURL field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetOrganizationsURL() string {
+	if c == nil || c.OrganizationsURL == nil {
+		return ""
+	}
+	return *c.OrganizationsURL
+}
+
+// GetReceivedEventsURL returns the ReceivedEventsURL field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetReceivedEventsURL() string {
+	if c == nil || c.ReceivedEventsURL == nil {
+		return ""
+	}
+	return *c.ReceivedEventsURL
+}
+
+// GetReposURL returns the ReposURL field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetReposURL() string {
+	if c == nil || c.ReposURL == nil {
+		return ""
+	}
+	return *c.ReposURL
+}
+
+// GetSiteAdmin returns the SiteAdmin field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetSiteAdmin() bool {
+	if c == nil || c.SiteAdmin == nil {
+		return false
+	}
+	return *c.SiteAdmin
+}
+
+// GetStarredURL returns the StarredURL field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetStarredURL() string {
+	if c == nil || c.StarredURL == nil {
+		return ""
+	}
+	return *c.StarredURL
+}
+
+// GetSubscriptionsURL returns the SubscriptionsURL field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetSubscriptionsURL() string {
+	if c == nil || c.SubscriptionsURL == nil {
+		return ""
+	}
+	return *c.SubscriptionsURL
+}
+
+// GetType returns the Type field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetType() string {
+	if c == nil || c.Type == nil {
+		return ""
+	}
+	return *c.Type
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetURL() string {
+	if c == nil || c.URL == nil {
+		return ""
+	}
+	return *c.URL
+}
+
+// GetAuthor returns the Author field.
+func (c *ContributorStats) GetAuthor() *Contributor {
+	if c == nil {
+		return nil
+	}
+	return c.Author
+}
+
+// GetTotal returns the Total field if it's non-nil, zero value otherwise.
+func (c *ContributorStats) GetTotal() int {
+	if c == nil || c.Total == nil {
+		return 0
+	}
+	return *c.Total
+}
+
+// GetCompletedAt returns the CompletedAt field if it's non-nil, zero value otherwise.
+func (c *CreateCheckRunOptions) GetCompletedAt() Timestamp {
+	if c == nil || c.CompletedAt == nil {
+		return Timestamp{}
+	}
+	return *c.CompletedAt
+}
+
+// GetConclusion returns the Conclusion field if it's non-nil, zero value otherwise.
+func (c *CreateCheckRunOptions) GetConclusion() string {
+	if c == nil || c.Conclusion == nil {
+		return ""
+	}
+	return *c.Conclusion
+}
+
+// GetDetailsURL returns the DetailsURL field if it's non-nil, zero value otherwise.
+func (c *CreateCheckRunOptions) GetDetailsURL() string {
+	if c == nil || c.DetailsURL == nil {
+		return ""
+	}
+	return *c.DetailsURL
+}
+
+// GetExternalID returns the ExternalID field if it's non-nil, zero value otherwise.
+func (c *CreateCheckRunOptions) GetExternalID() string {
+	if c == nil || c.ExternalID == nil {
+		return ""
+	}
+	return *c.ExternalID
+}
+
+// GetOutput returns the Output field.
+func (c *CreateCheckRunOptions) GetOutput() *CheckRunOutput {
+	if c == nil {
+		return nil
+	}
+	return c.Output
+}
+
+// GetStartedAt returns the StartedAt field if it's non-nil, zero value otherwise.
+func (c *CreateCheckRunOptions) GetStartedAt() Timestamp {
+	if c == nil || c.StartedAt == nil {
+		return Timestamp{}
+	}
+	return *c.StartedAt
+}
+
+// GetStatus returns the Status field if it's non-nil, zero value otherwise.
+func (c *CreateCheckRunOptions) GetStatus() string {
+	if c == nil || c.Status == nil {
+		return ""
+	}
+	return *c.Status
+}
+
+// GetHeadBranch returns the HeadBranch field if it's non-nil, zero value otherwise.
+func (c *CreateCheckSuiteOptions) GetHeadBranch() string {
+	if c == nil || c.HeadBranch == nil {
+		return ""
+	}
+	return *c.HeadBranch
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (c *CreateEvent) GetDescription() string {
+	if c == nil || c.Description == nil {
+		return ""
+	}
+	return *c.Description
+}
+
+// GetInstallation returns the Installation field.
+func (c *CreateEvent) GetInstallation() *Installation {
+	if c == nil {
+		return nil
+	}
+	return c.Installation
+}
+
+// GetMasterBranch returns the MasterBranch field if it's non-nil, zero value otherwise.
+func (c *CreateEvent) GetMasterBranch() string {
+	if c == nil || c.MasterBranch == nil {
+		return ""
+	}
+	return *c.MasterBranch
+}
+
+// GetPusherType returns the PusherType field if it's non-nil, zero value otherwise.
+func (c *CreateEvent) GetPusherType() string {
+	if c == nil || c.PusherType == nil {
+		return ""
+	}
+	return *c.PusherType
+}
+
+// GetRef returns the Ref field if it's non-nil, zero value otherwise.
+func (c *CreateEvent) GetRef() string {
+	if c == nil || c.Ref == nil {
+		return ""
+	}
+	return *c.Ref
+}
+
+// GetRefType returns the RefType field if it's non-nil, zero value otherwise.
+func (c *CreateEvent) GetRefType() string {
+	if c == nil || c.RefType == nil {
+		return ""
+	}
+	return *c.RefType
+}
+
+// GetRepo returns the Repo field.
+func (c *CreateEvent) GetRepo() *Repository {
+	if c == nil {
+		return nil
+	}
+	return c.Repo
+}
+
+// GetSender returns the Sender field.
+func (c *CreateEvent) GetSender() *User {
+	if c == nil {
+		return nil
+	}
+	return c.Sender
+}
+
+// GetEmail returns the Email field if it's non-nil, zero value otherwise.
+func (c *CreateOrgInvitationOptions) GetEmail() string {
+	if c == nil || c.Email == nil {
+		return ""
+	}
+	return *c.Email
+}
+
+// GetInviteeID returns the InviteeID field if it's non-nil, zero value otherwise.
+func (c *CreateOrgInvitationOptions) GetInviteeID() int64 {
+	if c == nil || c.InviteeID == nil {
+		return 0
+	}
+	return *c.InviteeID
+}
+
+// GetRole returns the Role field if it's non-nil, zero value otherwise.
+func (c *CreateOrgInvitationOptions) GetRole() string {
+	if c == nil || c.Role == nil {
+		return ""
+	}
+	return *c.Role
+}
+
+// GetInstallation returns the Installation field.
+func (d *DeleteEvent) GetInstallation() *Installation {
+	if d == nil {
+		return nil
+	}
+	return d.Installation
+}
+
+// GetPusherType returns the PusherType field if it's non-nil, zero value otherwise.
+func (d *DeleteEvent) GetPusherType() string {
+	if d == nil || d.PusherType == nil {
+		return ""
+	}
+	return *d.PusherType
+}
+
+// GetRef returns the Ref field if it's non-nil, zero value otherwise.
+func (d *DeleteEvent) GetRef() string {
+	if d == nil || d.Ref == nil {
+		return ""
+	}
+	return *d.Ref
+}
+
+// GetRefType returns the RefType field if it's non-nil, zero value otherwise.
+func (d *DeleteEvent) GetRefType() string {
+	if d == nil || d.RefType == nil {
+		return ""
+	}
+	return *d.RefType
+}
+
+// GetRepo returns the Repo field.
+func (d *DeleteEvent) GetRepo() *Repository {
+	if d == nil {
+		return nil
+	}
+	return d.Repo
+}
+
+// GetSender returns the Sender field.
+func (d *DeleteEvent) GetSender() *User {
+	if d == nil {
+		return nil
+	}
+	return d.Sender
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (d *Deployment) GetCreatedAt() Timestamp {
+	if d == nil || d.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *d.CreatedAt
+}
+
+// GetCreator returns the Creator field.
+func (d *Deployment) GetCreator() *User {
+	if d == nil {
+		return nil
+	}
+	return d.Creator
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (d *Deployment) GetDescription() string {
+	if d == nil || d.Description == nil {
+		return ""
+	}
+	return *d.Description
+}
+
+// GetEnvironment returns the Environment field if it's non-nil, zero value otherwise.
+func (d *Deployment) GetEnvironment() string {
+	if d == nil || d.Environment == nil {
+		return ""
+	}
+	return *d.Environment
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (d *Deployment) GetID() int64 {
+	if d == nil || d.ID == nil {
+		return 0
+	}
+	return *d.ID
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (d *Deployment) GetNodeID() string {
+	if d == nil || d.NodeID == nil {
+		return ""
+	}
+	return *d.NodeID
+}
+
+// GetRef returns the Ref field if it's non-nil, zero value otherwise.
+func (d *Deployment) GetRef() string {
+	if d == nil || d.Ref == nil {
+		return ""
+	}
+	return *d.Ref
+}
+
+// GetRepositoryURL returns the RepositoryURL field if it's non-nil, zero value otherwise.
+func (d *Deployment) GetRepositoryURL() string {
+	if d == nil || d.RepositoryURL == nil {
+		return ""
+	}
+	return *d.RepositoryURL
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (d *Deployment) GetSHA() string {
+	if d == nil || d.SHA == nil {
+		return ""
+	}
+	return *d.SHA
+}
+
+// GetStatusesURL returns the StatusesURL field if it's non-nil, zero value otherwise.
+func (d *Deployment) GetStatusesURL() string {
+	if d == nil || d.StatusesURL == nil {
+		return ""
+	}
+	return *d.StatusesURL
+}
+
+// GetTask returns the Task field if it's non-nil, zero value otherwise.
+func (d *Deployment) GetTask() string {
+	if d == nil || d.Task == nil {
+		return ""
+	}
+	return *d.Task
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (d *Deployment) GetUpdatedAt() Timestamp {
+	if d == nil || d.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *d.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (d *Deployment) GetURL() string {
+	if d == nil || d.URL == nil {
+		return ""
+	}
+	return *d.URL
+}
+
+// GetDeployment returns the Deployment field.
+func (d *DeploymentEvent) GetDeployment() *Deployment {
+	if d == nil {
+		return nil
+	}
+	return d.Deployment
+}
+
+// GetInstallation returns the Installation field.
+func (d *DeploymentEvent) GetInstallation() *Installation {
+	if d == nil {
+		return nil
+	}
+	return d.Installation
+}
+
+// GetRepo returns the Repo field.
+func (d *DeploymentEvent) GetRepo() *Repository {
+	if d == nil {
+		return nil
+	}
+	return d.Repo
+}
+
+// GetSender returns the Sender field.
+func (d *DeploymentEvent) GetSender() *User {
+	if d == nil {
+		return nil
+	}
+	return d.Sender
+}
+
+// GetAutoMerge returns the AutoMerge field if it's non-nil, zero value otherwise.
+func (d *DeploymentRequest) GetAutoMerge() bool {
+	if d == nil || d.AutoMerge == nil {
+		return false
+	}
+	return *d.AutoMerge
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (d *DeploymentRequest) GetDescription() string {
+	if d == nil || d.Description == nil {
+		return ""
+	}
+	return *d.Description
+}
+
+// GetEnvironment returns the Environment field if it's non-nil, zero value otherwise.
+func (d *DeploymentRequest) GetEnvironment() string {
+	if d == nil || d.Environment == nil {
+		return ""
+	}
+	return *d.Environment
+}
+
+// GetPayload returns the Payload field if it's non-nil, zero value otherwise.
+func (d *DeploymentRequest) GetPayload() string {
+	if d == nil || d.Payload == nil {
+		return ""
+	}
+	return *d.Payload
+}
+
+// GetProductionEnvironment returns the ProductionEnvironment field if it's non-nil, zero value otherwise.
+func (d *DeploymentRequest) GetProductionEnvironment() bool {
+	if d == nil || d.ProductionEnvironment == nil {
+		return false
+	}
+	return *d.ProductionEnvironment
+}
+
+// GetRef returns the Ref field if it's non-nil, zero value otherwise.
+func (d *DeploymentRequest) GetRef() string {
+	if d == nil || d.Ref == nil {
+		return ""
+	}
+	return *d.Ref
+}
+
+// GetRequiredContexts returns the RequiredContexts field if it's non-nil, zero value otherwise.
+func (d *DeploymentRequest) GetRequiredContexts() []string {
+	if d == nil || d.RequiredContexts == nil {
+		return nil
+	}
+	return *d.RequiredContexts
+}
+
+// GetTask returns the Task field if it's non-nil, zero value otherwise.
+func (d *DeploymentRequest) GetTask() string {
+	if d == nil || d.Task == nil {
+		return ""
+	}
+	return *d.Task
+}
+
+// GetTransientEnvironment returns the TransientEnvironment field if it's non-nil, zero value otherwise.
+func (d *DeploymentRequest) GetTransientEnvironment() bool {
+	if d == nil || d.TransientEnvironment == nil {
+		return false
+	}
+	return *d.TransientEnvironment
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatus) GetCreatedAt() Timestamp {
+	if d == nil || d.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *d.CreatedAt
+}
+
+// GetCreator returns the Creator field.
+func (d *DeploymentStatus) GetCreator() *User {
+	if d == nil {
+		return nil
+	}
+	return d.Creator
+}
+
+// GetDeploymentURL returns the DeploymentURL field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatus) GetDeploymentURL() string {
+	if d == nil || d.DeploymentURL == nil {
+		return ""
+	}
+	return *d.DeploymentURL
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatus) GetDescription() string {
+	if d == nil || d.Description == nil {
+		return ""
+	}
+	return *d.Description
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatus) GetID() int64 {
+	if d == nil || d.ID == nil {
+		return 0
+	}
+	return *d.ID
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatus) GetNodeID() string {
+	if d == nil || d.NodeID == nil {
+		return ""
+	}
+	return *d.NodeID
+}
+
+// GetRepositoryURL returns the RepositoryURL field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatus) GetRepositoryURL() string {
+	if d == nil || d.RepositoryURL == nil {
+		return ""
+	}
+	return *d.RepositoryURL
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatus) GetState() string {
+	if d == nil || d.State == nil {
+		return ""
+	}
+	return *d.State
+}
+
+// GetTargetURL returns the TargetURL field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatus) GetTargetURL() string {
+	if d == nil || d.TargetURL == nil {
+		return ""
+	}
+	return *d.TargetURL
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatus) GetUpdatedAt() Timestamp {
+	if d == nil || d.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *d.UpdatedAt
+}
+
+// GetDeployment returns the Deployment field.
+func (d *DeploymentStatusEvent) GetDeployment() *Deployment {
+	if d == nil {
+		return nil
+	}
+	return d.Deployment
+}
+
+// GetDeploymentStatus returns the DeploymentStatus field.
+func (d *DeploymentStatusEvent) GetDeploymentStatus() *DeploymentStatus {
+	if d == nil {
+		return nil
+	}
+	return d.DeploymentStatus
+}
+
+// GetInstallation returns the Installation field.
+func (d *DeploymentStatusEvent) GetInstallation() *Installation {
+	if d == nil {
+		return nil
+	}
+	return d.Installation
+}
+
+// GetRepo returns the Repo field.
+func (d *DeploymentStatusEvent) GetRepo() *Repository {
+	if d == nil {
+		return nil
+	}
+	return d.Repo
+}
+
+// GetSender returns the Sender field.
+func (d *DeploymentStatusEvent) GetSender() *User {
+	if d == nil {
+		return nil
+	}
+	return d.Sender
+}
+
+// GetAutoInactive returns the AutoInactive field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatusRequest) GetAutoInactive() bool {
+	if d == nil || d.AutoInactive == nil {
+		return false
+	}
+	return *d.AutoInactive
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatusRequest) GetDescription() string {
+	if d == nil || d.Description == nil {
+		return ""
+	}
+	return *d.Description
+}
+
+// GetEnvironment returns the Environment field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatusRequest) GetEnvironment() string {
+	if d == nil || d.Environment == nil {
+		return ""
+	}
+	return *d.Environment
+}
+
+// GetEnvironmentURL returns the EnvironmentURL field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatusRequest) GetEnvironmentURL() string {
+	if d == nil || d.EnvironmentURL == nil {
+		return ""
+	}
+	return *d.EnvironmentURL
+}
+
+// GetLogURL returns the LogURL field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatusRequest) GetLogURL() string {
+	if d == nil || d.LogURL == nil {
+		return ""
+	}
+	return *d.LogURL
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatusRequest) GetState() string {
+	if d == nil || d.State == nil {
+		return ""
+	}
+	return *d.State
+}
+
+// GetAuthor returns the Author field.
+func (d *DiscussionComment) GetAuthor() *User {
+	if d == nil {
+		return nil
+	}
+	return d.Author
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (d *DiscussionComment) GetBody() string {
+	if d == nil || d.Body == nil {
+		return ""
+	}
+	return *d.Body
+}
+
+// GetBodyHTML returns the BodyHTML field if it's non-nil, zero value otherwise.
+func (d *DiscussionComment) GetBodyHTML() string {
+	if d == nil || d.BodyHTML == nil {
+		return ""
+	}
+	return *d.BodyHTML
+}
+
+// GetBodyVersion returns the BodyVersion field if it's non-nil, zero value otherwise.
+func (d *DiscussionComment) GetBodyVersion() string {
+	if d == nil || d.BodyVersion == nil {
+		return ""
+	}
+	return *d.BodyVersion
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (d *DiscussionComment) GetCreatedAt() Timestamp {
+	if d == nil || d.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *d.CreatedAt
+}
+
+// GetDiscussionURL returns the DiscussionURL field if it's non-nil, zero value otherwise.
+func (d *DiscussionComment) GetDiscussionURL() string {
+	if d == nil || d.DiscussionURL == nil {
+		return ""
+	}
+	return *d.DiscussionURL
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (d *DiscussionComment) GetHTMLURL() string {
+	if d == nil || d.HTMLURL == nil {
+		return ""
+	}
+	return *d.HTMLURL
+}
+
+// GetLastEditedAt returns the LastEditedAt field if it's non-nil, zero value otherwise.
+func (d *DiscussionComment) GetLastEditedAt() Timestamp {
+	if d == nil || d.LastEditedAt == nil {
+		return Timestamp{}
+	}
+	return *d.LastEditedAt
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (d *DiscussionComment) GetNodeID() string {
+	if d == nil || d.NodeID == nil {
+		return ""
+	}
+	return *d.NodeID
+}
+
+// GetNumber returns the Number field if it's non-nil, zero value otherwise.
+func (d *DiscussionComment) GetNumber() int {
+	if d == nil || d.Number == nil {
+		return 0
+	}
+	return *d.Number
+}
+
+// GetReactions returns the Reactions field.
+func (d *DiscussionComment) GetReactions() *Reactions {
+	if d == nil {
+		return nil
+	}
+	return d.Reactions
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (d *DiscussionComment) GetUpdatedAt() Timestamp {
+	if d == nil || d.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *d.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (d *DiscussionComment) GetURL() string {
+	if d == nil || d.URL == nil {
+		return ""
+	}
+	return *d.URL
+}
+
+// GetTeams returns the Teams field if it's non-nil, zero value otherwise.
+func (d *DismissalRestrictionsRequest) GetTeams() []string {
+	if d == nil || d.Teams == nil {
+		return nil
+	}
+	return *d.Teams
+}
+
+// GetUsers returns the Users field if it's non-nil, zero value otherwise.
+func (d *DismissalRestrictionsRequest) GetUsers() []string {
+	if d == nil || d.Users == nil {
+		return nil
+	}
+	return *d.Users
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (d *DraftReviewComment) GetBody() string {
+	if d == nil || d.Body == nil {
+		return ""
+	}
+	return *d.Body
+}
+
+// GetPath returns the Path field if it's non-nil, zero value otherwise.
+func (d *DraftReviewComment) GetPath() string {
+	if d == nil || d.Path == nil {
+		return ""
+	}
+	return *d.Path
+}
+
+// GetPosition returns the Position field if it's non-nil, zero value otherwise.
+func (d *DraftReviewComment) GetPosition() int {
+	if d == nil || d.Position == nil {
+		return 0
+	}
+	return *d.Position
+}
+
+// GetActor returns the Actor field.
+func (e *Event) GetActor() *User {
+	if e == nil {
+		return nil
+	}
+	return e.Actor
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (e *Event) GetCreatedAt() time.Time {
+	if e == nil || e.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *e.CreatedAt
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (e *Event) GetID() string {
+	if e == nil || e.ID == nil {
+		return ""
+	}
+	return *e.ID
+}
+
+// GetOrg returns the Org field.
+func (e *Event) GetOrg() *Organization {
+	if e == nil {
+		return nil
+	}
+	return e.Org
+}
+
+// GetPublic returns the Public field if it's non-nil, zero value otherwise.
+func (e *Event) GetPublic() bool {
+	if e == nil || e.Public == nil {
+		return false
+	}
+	return *e.Public
+}
+
+// GetRawPayload returns the RawPayload field if it's non-nil, zero value otherwise.
+func (e *Event) GetRawPayload() json.RawMessage {
+	if e == nil || e.RawPayload == nil {
+		return json.RawMessage{}
+	}
+	return *e.RawPayload
+}
+
+// GetRepo returns the Repo field.
+func (e *Event) GetRepo() *Repository {
+	if e == nil {
+		return nil
+	}
+	return e.Repo
+}
+
+// GetType returns the Type field if it's non-nil, zero value otherwise.
+func (e *Event) GetType() string {
+	if e == nil || e.Type == nil {
+		return ""
+	}
+	return *e.Type
+}
+
+// GetHRef returns the HRef field if it's non-nil, zero value otherwise.
+func (f *FeedLink) GetHRef() string {
+	if f == nil || f.HRef == nil {
+		return ""
+	}
+	return *f.HRef
+}
+
+// GetType returns the Type field if it's non-nil, zero value otherwise.
+func (f *FeedLink) GetType() string {
+	if f == nil || f.Type == nil {
+		return ""
+	}
+	return *f.Type
+}
+
+// GetCurrentUserActorURL returns the CurrentUserActorURL field if it's non-nil, zero value otherwise.
+func (f *Feeds) GetCurrentUserActorURL() string {
+	if f == nil || f.CurrentUserActorURL == nil {
+		return ""
+	}
+	return *f.CurrentUserActorURL
+}
+
+// GetCurrentUserOrganizationURL returns the CurrentUserOrganizationURL field if it's non-nil, zero value otherwise.
+func (f *Feeds) GetCurrentUserOrganizationURL() string {
+	if f == nil || f.CurrentUserOrganizationURL == nil {
+		return ""
+	}
+	return *f.CurrentUserOrganizationURL
+}
+
+// GetCurrentUserPublicURL returns the CurrentUserPublicURL field if it's non-nil, zero value otherwise.
+func (f *Feeds) GetCurrentUserPublicURL() string {
+	if f == nil || f.CurrentUserPublicURL == nil {
+		return ""
+	}
+	return *f.CurrentUserPublicURL
+}
+
+// GetCurrentUserURL returns the CurrentUserURL field if it's non-nil, zero value otherwise.
+func (f *Feeds) GetCurrentUserURL() string {
+	if f == nil || f.CurrentUserURL == nil {
+		return ""
+	}
+	return *f.CurrentUserURL
+}
+
+// GetTimelineURL returns the TimelineURL field if it's non-nil, zero value otherwise.
+func (f *Feeds) GetTimelineURL() string {
+	if f == nil || f.TimelineURL == nil {
+		return ""
+	}
+	return *f.TimelineURL
+}
+
+// GetUserURL returns the UserURL field if it's non-nil, zero value otherwise.
+func (f *Feeds) GetUserURL() string {
+	if f == nil || f.UserURL == nil {
+		return ""
+	}
+	return *f.UserURL
+}
+
+// GetForkee returns the Forkee field.
+func (f *ForkEvent) GetForkee() *Repository {
+	if f == nil {
+		return nil
+	}
+	return f.Forkee
+}
+
+// GetInstallation returns the Installation field.
+func (f *ForkEvent) GetInstallation() *Installation {
+	if f == nil {
+		return nil
+	}
+	return f.Installation
+}
+
+// GetRepo returns the Repo field.
+func (f *ForkEvent) GetRepo() *Repository {
+	if f == nil {
+		return nil
+	}
+	return f.Repo
+}
+
+// GetSender returns the Sender field.
+func (f *ForkEvent) GetSender() *User {
+	if f == nil {
+		return nil
+	}
+	return f.Sender
+}
+
+// GetComments returns the Comments field if it's non-nil, zero value otherwise.
+func (g *Gist) GetComments() int {
+	if g == nil || g.Comments == nil {
+		return 0
+	}
+	return *g.Comments
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (g *Gist) GetCreatedAt() time.Time {
+	if g == nil || g.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *g.CreatedAt
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (g *Gist) GetDescription() string {
+	if g == nil || g.Description == nil {
+		return ""
+	}
+	return *g.Description
+}
+
+// GetGitPullURL returns the GitPullURL field if it's non-nil, zero value otherwise.
+func (g *Gist) GetGitPullURL() string {
+	if g == nil || g.GitPullURL == nil {
+		return ""
+	}
+	return *g.GitPullURL
+}
+
+// GetGitPushURL returns the GitPushURL field if it's non-nil, zero value otherwise.
+func (g *Gist) GetGitPushURL() string {
+	if g == nil || g.GitPushURL == nil {
+		return ""
+	}
+	return *g.GitPushURL
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (g *Gist) GetHTMLURL() string {
+	if g == nil || g.HTMLURL == nil {
+		return ""
+	}
+	return *g.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (g *Gist) GetID() string {
+	if g == nil || g.ID == nil {
+		return ""
+	}
+	return *g.ID
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (g *Gist) GetNodeID() string {
+	if g == nil || g.NodeID == nil {
+		return ""
+	}
+	return *g.NodeID
+}
+
+// GetOwner returns the Owner field.
+func (g *Gist) GetOwner() *User {
+	if g == nil {
+		return nil
+	}
+	return g.Owner
+}
+
+// GetPublic returns the Public field if it's non-nil, zero value otherwise.
+func (g *Gist) GetPublic() bool {
+	if g == nil || g.Public == nil {
+		return false
+	}
+	return *g.Public
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (g *Gist) GetUpdatedAt() time.Time {
+	if g == nil || g.UpdatedAt == nil {
+		return time.Time{}
+	}
+	return *g.UpdatedAt
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (g *GistComment) GetBody() string {
+	if g == nil || g.Body == nil {
+		return ""
+	}
+	return *g.Body
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (g *GistComment) GetCreatedAt() time.Time {
+	if g == nil || g.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *g.CreatedAt
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (g *GistComment) GetID() int64 {
+	if g == nil || g.ID == nil {
+		return 0
+	}
+	return *g.ID
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (g *GistComment) GetURL() string {
+	if g == nil || g.URL == nil {
+		return ""
+	}
+	return *g.URL
+}
+
+// GetUser returns the User field.
+func (g *GistComment) GetUser() *User {
+	if g == nil {
+		return nil
+	}
+	return g.User
+}
+
+// GetChangeStatus returns the ChangeStatus field.
+func (g *GistCommit) GetChangeStatus() *CommitStats {
+	if g == nil {
+		return nil
+	}
+	return g.ChangeStatus
+}
+
+// GetCommittedAt returns the CommittedAt field if it's non-nil, zero value otherwise.
+func (g *GistCommit) GetCommittedAt() Timestamp {
+	if g == nil || g.CommittedAt == nil {
+		return Timestamp{}
+	}
+	return *g.CommittedAt
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (g *GistCommit) GetNodeID() string {
+	if g == nil || g.NodeID == nil {
+		return ""
+	}
+	return *g.NodeID
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (g *GistCommit) GetURL() string {
+	if g == nil || g.URL == nil {
+		return ""
+	}
+	return *g.URL
+}
+
+// GetUser returns the User field.
+func (g *GistCommit) GetUser() *User {
+	if g == nil {
+		return nil
+	}
+	return g.User
+}
+
+// GetVersion returns the Version field if it's non-nil, zero value otherwise.
+func (g *GistCommit) GetVersion() string {
+	if g == nil || g.Version == nil {
+		return ""
+	}
+	return *g.Version
+}
+
+// GetContent returns the Content field if it's non-nil, zero value otherwise.
+func (g *GistFile) GetContent() string {
+	if g == nil || g.Content == nil {
+		return ""
+	}
+	return *g.Content
+}
+
+// GetFilename returns the Filename field if it's non-nil, zero value otherwise.
+func (g *GistFile) GetFilename() string {
+	if g == nil || g.Filename == nil {
+		return ""
+	}
+	return *g.Filename
+}
+
+// GetLanguage returns the Language field if it's non-nil, zero value otherwise.
+func (g *GistFile) GetLanguage() string {
+	if g == nil || g.Language == nil {
+		return ""
+	}
+	return *g.Language
+}
+
+// GetRawURL returns the RawURL field if it's non-nil, zero value otherwise.
+func (g *GistFile) GetRawURL() string {
+	if g == nil || g.RawURL == nil {
+		return ""
+	}
+	return *g.RawURL
+}
+
+// GetSize returns the Size field if it's non-nil, zero value otherwise.
+func (g *GistFile) GetSize() int {
+	if g == nil || g.Size == nil {
+		return 0
+	}
+	return *g.Size
+}
+
+// GetType returns the Type field if it's non-nil, zero value otherwise.
+func (g *GistFile) GetType() string {
+	if g == nil || g.Type == nil {
+		return ""
+	}
+	return *g.Type
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (g *GistFork) GetCreatedAt() Timestamp {
+	if g == nil || g.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *g.CreatedAt
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (g *GistFork) GetID() string {
+	if g == nil || g.ID == nil {
+		return ""
+	}
+	return *g.ID
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (g *GistFork) GetNodeID() string {
+	if g == nil || g.NodeID == nil {
+		return ""
+	}
+	return *g.NodeID
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (g *GistFork) GetUpdatedAt() Timestamp {
+	if g == nil || g.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *g.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (g *GistFork) GetURL() string {
+	if g == nil || g.URL == nil {
+		return ""
+	}
+	return *g.URL
+}
+
+// GetUser returns the User field.
+func (g *GistFork) GetUser() *User {
+	if g == nil {
+		return nil
+	}
+	return g.User
+}
+
+// GetPrivateGists returns the PrivateGists field if it's non-nil, zero value otherwise.
+func (g *GistStats) GetPrivateGists() int {
+	if g == nil || g.PrivateGists == nil {
+		return 0
+	}
+	return *g.PrivateGists
+}
+
+// GetPublicGists returns the PublicGists field if it's non-nil, zero value otherwise.
+func (g *GistStats) GetPublicGists() int {
+	if g == nil || g.PublicGists == nil {
+		return 0
+	}
+	return *g.PublicGists
+}
+
+// GetTotalGists returns the TotalGists field if it's non-nil, zero value otherwise.
+func (g *GistStats) GetTotalGists() int {
+	if g == nil || g.TotalGists == nil {
+		return 0
+	}
+	return *g.TotalGists
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (g *GitHubAppAuthorizationEvent) GetAction() string {
+	if g == nil || g.Action == nil {
+		return ""
+	}
+	return *g.Action
+}
+
+// GetSender returns the Sender field.
+func (g *GitHubAppAuthorizationEvent) GetSender() *User {
+	if g == nil {
+		return nil
+	}
+	return g.Sender
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (g *Gitignore) GetName() string {
+	if g == nil || g.Name == nil {
+		return ""
+	}
+	return *g.Name
+}
+
+// GetSource returns the Source field if it's non-nil, zero value otherwise.
+func (g *Gitignore) GetSource() string {
+	if g == nil || g.Source == nil {
+		return ""
+	}
+	return *g.Source
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (g *GitObject) GetSHA() string {
+	if g == nil || g.SHA == nil {
+		return ""
+	}
+	return *g.SHA
+}
+
+// GetType returns the Type field if it's non-nil, zero value otherwise.
+func (g *GitObject) GetType() string {
+	if g == nil || g.Type == nil {
+		return ""
+	}
+	return *g.Type
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (g *GitObject) GetURL() string {
+	if g == nil || g.URL == nil {
+		return ""
+	}
+	return *g.URL
+}
+
+// GetInstallation returns the Installation field.
+func (g *GollumEvent) GetInstallation() *Installation {
+	if g == nil {
+		return nil
+	}
+	return g.Installation
+}
+
+// GetRepo returns the Repo field.
+func (g *GollumEvent) GetRepo() *Repository {
+	if g == nil {
+		return nil
+	}
+	return g.Repo
+}
+
+// GetSender returns the Sender field.
+func (g *GollumEvent) GetSender() *User {
+	if g == nil {
+		return nil
+	}
+	return g.Sender
+}
+
+// GetEmail returns the Email field if it's non-nil, zero value otherwise.
+func (g *GPGEmail) GetEmail() string {
+	if g == nil || g.Email == nil {
+		return ""
+	}
+	return *g.Email
+}
+
+// GetVerified returns the Verified field if it's non-nil, zero value otherwise.
+func (g *GPGEmail) GetVerified() bool {
+	if g == nil || g.Verified == nil {
+		return false
+	}
+	return *g.Verified
+}
+
+// GetCanCertify returns the CanCertify field if it's non-nil, zero value otherwise.
+func (g *GPGKey) GetCanCertify() bool {
+	if g == nil || g.CanCertify == nil {
+		return false
+	}
+	return *g.CanCertify
+}
+
+// GetCanEncryptComms returns the CanEncryptComms field if it's non-nil, zero value otherwise.
+func (g *GPGKey) GetCanEncryptComms() bool {
+	if g == nil || g.CanEncryptComms == nil {
+		return false
+	}
+	return *g.CanEncryptComms
+}
+
+// GetCanEncryptStorage returns the CanEncryptStorage field if it's non-nil, zero value otherwise.
+func (g *GPGKey) GetCanEncryptStorage() bool {
+	if g == nil || g.CanEncryptStorage == nil {
+		return false
+	}
+	return *g.CanEncryptStorage
+}
+
+// GetCanSign returns the CanSign field if it's non-nil, zero value otherwise.
+func (g *GPGKey) GetCanSign() bool {
+	if g == nil || g.CanSign == nil {
+		return false
+	}
+	return *g.CanSign
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (g *GPGKey) GetCreatedAt() time.Time {
+	if g == nil || g.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *g.CreatedAt
+}
+
+// GetExpiresAt returns the ExpiresAt field if it's non-nil, zero value otherwise.
+func (g *GPGKey) GetExpiresAt() time.Time {
+	if g == nil || g.ExpiresAt == nil {
+		return time.Time{}
+	}
+	return *g.ExpiresAt
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (g *GPGKey) GetID() int64 {
+	if g == nil || g.ID == nil {
+		return 0
+	}
+	return *g.ID
+}
+
+// GetKeyID returns the KeyID field if it's non-nil, zero value otherwise.
+func (g *GPGKey) GetKeyID() string {
+	if g == nil || g.KeyID == nil {
+		return ""
+	}
+	return *g.KeyID
+}
+
+// GetPrimaryKeyID returns the PrimaryKeyID field if it's non-nil, zero value otherwise.
+func (g *GPGKey) GetPrimaryKeyID() int64 {
+	if g == nil || g.PrimaryKeyID == nil {
+		return 0
+	}
+	return *g.PrimaryKeyID
+}
+
+// GetPublicKey returns the PublicKey field if it's non-nil, zero value otherwise.
+func (g *GPGKey) GetPublicKey() string {
+	if g == nil || g.PublicKey == nil {
+		return ""
+	}
+	return *g.PublicKey
+}
+
+// GetApp returns the App field.
+func (g *Grant) GetApp() *AuthorizationApp {
+	if g == nil {
+		return nil
+	}
+	return g.App
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (g *Grant) GetCreatedAt() Timestamp {
+	if g == nil || g.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *g.CreatedAt
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (g *Grant) GetID() int64 {
+	if g == nil || g.ID == nil {
+		return 0
+	}
+	return *g.ID
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (g *Grant) GetUpdatedAt() Timestamp {
+	if g == nil || g.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *g.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (g *Grant) GetURL() string {
+	if g == nil || g.URL == nil {
+		return ""
+	}
+	return *g.URL
+}
+
+// GetActive returns the Active field if it's non-nil, zero value otherwise.
+func (h *Hook) GetActive() bool {
+	if h == nil || h.Active == nil {
+		return false
+	}
+	return *h.Active
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (h *Hook) GetCreatedAt() time.Time {
+	if h == nil || h.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *h.CreatedAt
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (h *Hook) GetID() int64 {
+	if h == nil || h.ID == nil {
+		return 0
+	}
+	return *h.ID
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (h *Hook) GetUpdatedAt() time.Time {
+	if h == nil || h.UpdatedAt == nil {
+		return time.Time{}
+	}
+	return *h.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (h *Hook) GetURL() string {
+	if h == nil || h.URL == nil {
+		return ""
+	}
+	return *h.URL
+}
+
+// GetActiveHooks returns the ActiveHooks field if it's non-nil, zero value otherwise.
+func (h *HookStats) GetActiveHooks() int {
+	if h == nil || h.ActiveHooks == nil {
+		return 0
+	}
+	return *h.ActiveHooks
+}
+
+// GetInactiveHooks returns the InactiveHooks field if it's non-nil, zero value otherwise.
+func (h *HookStats) GetInactiveHooks() int {
+	if h == nil || h.InactiveHooks == nil {
+		return 0
+	}
+	return *h.InactiveHooks
+}
+
+// GetTotalHooks returns the TotalHooks field if it's non-nil, zero value otherwise.
+func (h *HookStats) GetTotalHooks() int {
+	if h == nil || h.TotalHooks == nil {
+		return 0
+	}
+	return *h.TotalHooks
+}
+
+// GetAuthorsCount returns the AuthorsCount field if it's non-nil, zero value otherwise.
+func (i *Import) GetAuthorsCount() int {
+	if i == nil || i.AuthorsCount == nil {
+		return 0
+	}
+	return *i.AuthorsCount
+}
+
+// GetAuthorsURL returns the AuthorsURL field if it's non-nil, zero value otherwise.
+func (i *Import) GetAuthorsURL() string {
+	if i == nil || i.AuthorsURL == nil {
+		return ""
+	}
+	return *i.AuthorsURL
+}
+
+// GetCommitCount returns the CommitCount field if it's non-nil, zero value otherwise.
+func (i *Import) GetCommitCount() int {
+	if i == nil || i.CommitCount == nil {
+		return 0
+	}
+	return *i.CommitCount
+}
+
+// GetFailedStep returns the FailedStep field if it's non-nil, zero value otherwise.
+func (i *Import) GetFailedStep() string {
+	if i == nil || i.FailedStep == nil {
+		return ""
+	}
+	return *i.FailedStep
+}
+
+// GetHasLargeFiles returns the HasLargeFiles field if it's non-nil, zero value otherwise.
+func (i *Import) GetHasLargeFiles() bool {
+	if i == nil || i.HasLargeFiles == nil {
+		return false
+	}
+	return *i.HasLargeFiles
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (i *Import) GetHTMLURL() string {
+	if i == nil || i.HTMLURL == nil {
+		return ""
+	}
+	return *i.HTMLURL
+}
+
+// GetHumanName returns the HumanName field if it's non-nil, zero value otherwise.
+func (i *Import) GetHumanName() string {
+	if i == nil || i.HumanName == nil {
+		return ""
+	}
+	return *i.HumanName
+}
+
+// GetLargeFilesCount returns the LargeFilesCount field if it's non-nil, zero value otherwise.
+func (i *Import) GetLargeFilesCount() int {
+	if i == nil || i.LargeFilesCount == nil {
+		return 0
+	}
+	return *i.LargeFilesCount
+}
+
+// GetLargeFilesSize returns the LargeFilesSize field if it's non-nil, zero value otherwise.
+func (i *Import) GetLargeFilesSize() int {
+	if i == nil || i.LargeFilesSize == nil {
+		return 0
+	}
+	return *i.LargeFilesSize
+}
+
+// GetMessage returns the Message field if it's non-nil, zero value otherwise.
+func (i *Import) GetMessage() string {
+	if i == nil || i.Message == nil {
+		return ""
+	}
+	return *i.Message
+}
+
+// GetPercent returns the Percent field if it's non-nil, zero value otherwise.
+func (i *Import) GetPercent() int {
+	if i == nil || i.Percent == nil {
+		return 0
+	}
+	return *i.Percent
+}
+
+// GetPushPercent returns the PushPercent field if it's non-nil, zero value otherwise.
+func (i *Import) GetPushPercent() int {
+	if i == nil || i.PushPercent == nil {
+		return 0
+	}
+	return *i.PushPercent
+}
+
+// GetRepositoryURL returns the RepositoryURL field if it's non-nil, zero value otherwise.
+func (i *Import) GetRepositoryURL() string {
+	if i == nil || i.RepositoryURL == nil {
+		return ""
+	}
+	return *i.RepositoryURL
+}
+
+// GetStatus returns the Status field if it's non-nil, zero value otherwise.
+func (i *Import) GetStatus() string {
+	if i == nil || i.Status == nil {
+		return ""
+	}
+	return *i.Status
+}
+
+// GetStatusText returns the StatusText field if it's non-nil, zero value otherwise.
+func (i *Import) GetStatusText() string {
+	if i == nil || i.StatusText == nil {
+		return ""
+	}
+	return *i.StatusText
+}
+
+// GetTFVCProject returns the TFVCProject field if it's non-nil, zero value otherwise.
+func (i *Import) GetTFVCProject() string {
+	if i == nil || i.TFVCProject == nil {
+		return ""
+	}
+	return *i.TFVCProject
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (i *Import) GetURL() string {
+	if i == nil || i.URL == nil {
+		return ""
+	}
+	return *i.URL
+}
+
+// GetUseLFS returns the UseLFS field if it's non-nil, zero value otherwise.
+func (i *Import) GetUseLFS() string {
+	if i == nil || i.UseLFS == nil {
+		return ""
+	}
+	return *i.UseLFS
+}
+
+// GetVCS returns the VCS field if it's non-nil, zero value otherwise.
+func (i *Import) GetVCS() string {
+	if i == nil || i.VCS == nil {
+		return ""
+	}
+	return *i.VCS
+}
+
+// GetVCSPassword returns the VCSPassword field if it's non-nil, zero value otherwise.
+func (i *Import) GetVCSPassword() string {
+	if i == nil || i.VCSPassword == nil {
+		return ""
+	}
+	return *i.VCSPassword
+}
+
+// GetVCSURL returns the VCSURL field if it's non-nil, zero value otherwise.
+func (i *Import) GetVCSURL() string {
+	if i == nil || i.VCSURL == nil {
+		return ""
+	}
+	return *i.VCSURL
+}
+
+// GetVCSUsername returns the VCSUsername field if it's non-nil, zero value otherwise.
+func (i *Import) GetVCSUsername() string {
+	if i == nil || i.VCSUsername == nil {
+		return ""
+	}
+	return *i.VCSUsername
+}
+
+// GetAccessTokensURL returns the AccessTokensURL field if it's non-nil, zero value otherwise.
+func (i *Installation) GetAccessTokensURL() string {
+	if i == nil || i.AccessTokensURL == nil {
+		return ""
+	}
+	return *i.AccessTokensURL
+}
+
+// GetAccount returns the Account field.
+func (i *Installation) GetAccount() *User {
+	if i == nil {
+		return nil
+	}
+	return i.Account
+}
+
+// GetAppID returns the AppID field if it's non-nil, zero value otherwise.
+func (i *Installation) GetAppID() int64 {
+	if i == nil || i.AppID == nil {
+		return 0
+	}
+	return *i.AppID
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (i *Installation) GetCreatedAt() Timestamp {
+	if i == nil || i.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *i.CreatedAt
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (i *Installation) GetHTMLURL() string {
+	if i == nil || i.HTMLURL == nil {
+		return ""
+	}
+	return *i.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (i *Installation) GetID() int64 {
+	if i == nil || i.ID == nil {
+		return 0
+	}
+	return *i.ID
+}
+
+// GetPermissions returns the Permissions field.
+func (i *Installation) GetPermissions() *InstallationPermissions {
+	if i == nil {
+		return nil
+	}
+	return i.Permissions
+}
+
+// GetRepositoriesURL returns the RepositoriesURL field if it's non-nil, zero value otherwise.
+func (i *Installation) GetRepositoriesURL() string {
+	if i == nil || i.RepositoriesURL == nil {
+		return ""
+	}
+	return *i.RepositoriesURL
+}
+
+// GetRepositorySelection returns the RepositorySelection field if it's non-nil, zero value otherwise.
+func (i *Installation) GetRepositorySelection() string {
+	if i == nil || i.RepositorySelection == nil {
+		return ""
+	}
+	return *i.RepositorySelection
+}
+
+// GetSingleFileName returns the SingleFileName field if it's non-nil, zero value otherwise.
+func (i *Installation) GetSingleFileName() string {
+	if i == nil || i.SingleFileName == nil {
+		return ""
+	}
+	return *i.SingleFileName
+}
+
+// GetTargetID returns the TargetID field if it's non-nil, zero value otherwise.
+func (i *Installation) GetTargetID() int64 {
+	if i == nil || i.TargetID == nil {
+		return 0
+	}
+	return *i.TargetID
+}
+
+// GetTargetType returns the TargetType field if it's non-nil, zero value otherwise.
+func (i *Installation) GetTargetType() string {
+	if i == nil || i.TargetType == nil {
+		return ""
+	}
+	return *i.TargetType
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (i *Installation) GetUpdatedAt() Timestamp {
+	if i == nil || i.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *i.UpdatedAt
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (i *InstallationEvent) GetAction() string {
+	if i == nil || i.Action == nil {
+		return ""
+	}
+	return *i.Action
+}
+
+// GetInstallation returns the Installation field.
+func (i *InstallationEvent) GetInstallation() *Installation {
+	if i == nil {
+		return nil
+	}
+	return i.Installation
+}
+
+// GetSender returns the Sender field.
+func (i *InstallationEvent) GetSender() *User {
+	if i == nil {
+		return nil
+	}
+	return i.Sender
+}
+
+// GetContents returns the Contents field if it's non-nil, zero value otherwise.
+func (i *InstallationPermissions) GetContents() string {
+	if i == nil || i.Contents == nil {
+		return ""
+	}
+	return *i.Contents
+}
+
+// GetIssues returns the Issues field if it's non-nil, zero value otherwise.
+func (i *InstallationPermissions) GetIssues() string {
+	if i == nil || i.Issues == nil {
+		return ""
+	}
+	return *i.Issues
+}
+
+// GetMetadata returns the Metadata field if it's non-nil, zero value otherwise.
+func (i *InstallationPermissions) GetMetadata() string {
+	if i == nil || i.Metadata == nil {
+		return ""
+	}
+	return *i.Metadata
+}
+
+// GetSingleFile returns the SingleFile field if it's non-nil, zero value otherwise.
+func (i *InstallationPermissions) GetSingleFile() string {
+	if i == nil || i.SingleFile == nil {
+		return ""
+	}
+	return *i.SingleFile
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (i *InstallationRepositoriesEvent) GetAction() string {
+	if i == nil || i.Action == nil {
+		return ""
+	}
+	return *i.Action
+}
+
+// GetInstallation returns the Installation field.
+func (i *InstallationRepositoriesEvent) GetInstallation() *Installation {
+	if i == nil {
+		return nil
+	}
+	return i.Installation
+}
+
+// GetRepositorySelection returns the RepositorySelection field if it's non-nil, zero value otherwise.
+func (i *InstallationRepositoriesEvent) GetRepositorySelection() string {
+	if i == nil || i.RepositorySelection == nil {
+		return ""
+	}
+	return *i.RepositorySelection
+}
+
+// GetSender returns the Sender field.
+func (i *InstallationRepositoriesEvent) GetSender() *User {
+	if i == nil {
+		return nil
+	}
+	return i.Sender
+}
+
+// GetExpiresAt returns the ExpiresAt field if it's non-nil, zero value otherwise.
+func (i *InstallationToken) GetExpiresAt() time.Time {
+	if i == nil || i.ExpiresAt == nil {
+		return time.Time{}
+	}
+	return *i.ExpiresAt
+}
+
+// GetToken returns the Token field if it's non-nil, zero value otherwise.
+func (i *InstallationToken) GetToken() string {
+	if i == nil || i.Token == nil {
+		return ""
+	}
+	return *i.Token
+}
+
+// GetExpiresAt returns the ExpiresAt field if it's non-nil, zero value otherwise.
+func (i *InteractionRestriction) GetExpiresAt() Timestamp {
+	if i == nil || i.ExpiresAt == nil {
+		return Timestamp{}
+	}
+	return *i.ExpiresAt
+}
+
+// GetLimit returns the Limit field if it's non-nil, zero value otherwise.
+func (i *InteractionRestriction) GetLimit() string {
+	if i == nil || i.Limit == nil {
+		return ""
+	}
+	return *i.Limit
+}
+
+// GetOrigin returns the Origin field if it's non-nil, zero value otherwise.
+func (i *InteractionRestriction) GetOrigin() string {
+	if i == nil || i.Origin == nil {
+		return ""
+	}
+	return *i.Origin
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (i *Invitation) GetCreatedAt() time.Time {
+	if i == nil || i.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *i.CreatedAt
+}
+
+// GetEmail returns the Email field if it's non-nil, zero value otherwise.
+func (i *Invitation) GetEmail() string {
+	if i == nil || i.Email == nil {
+		return ""
+	}
+	return *i.Email
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (i *Invitation) GetID() int64 {
+	if i == nil || i.ID == nil {
+		return 0
+	}
+	return *i.ID
+}
+
+// GetInvitationTeamURL returns the InvitationTeamURL field if it's non-nil, zero value otherwise.
+func (i *Invitation) GetInvitationTeamURL() string {
+	if i == nil || i.InvitationTeamURL == nil {
+		return ""
+	}
+	return *i.InvitationTeamURL
+}
+
+// GetInviter returns the Inviter field.
+func (i *Invitation) GetInviter() *User {
+	if i == nil {
+		return nil
+	}
+	return i.Inviter
+}
+
+// GetLogin returns the Login field if it's non-nil, zero value otherwise.
+func (i *Invitation) GetLogin() string {
+	if i == nil || i.Login == nil {
+		return ""
+	}
+	return *i.Login
+}
+
+// GetRole returns the Role field if it's non-nil, zero value otherwise.
+func (i *Invitation) GetRole() string {
+	if i == nil || i.Role == nil {
+		return ""
+	}
+	return *i.Role
+}
+
+// GetTeamCount returns the TeamCount field if it's non-nil, zero value otherwise.
+func (i *Invitation) GetTeamCount() int {
+	if i == nil || i.TeamCount == nil {
+		return 0
+	}
+	return *i.TeamCount
+}
+
+// GetActiveLockReason returns the ActiveLockReason field if it's non-nil, zero value otherwise.
+func (i *Issue) GetActiveLockReason() string {
+	if i == nil || i.ActiveLockReason == nil {
+		return ""
+	}
+	return *i.ActiveLockReason
+}
+
+// GetAssignee returns the Assignee field.
+func (i *Issue) GetAssignee() *User {
+	if i == nil {
+		return nil
+	}
+	return i.Assignee
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (i *Issue) GetBody() string {
+	if i == nil || i.Body == nil {
+		return ""
+	}
+	return *i.Body
+}
+
+// GetClosedAt returns the ClosedAt field if it's non-nil, zero value otherwise.
+func (i *Issue) GetClosedAt() time.Time {
+	if i == nil || i.ClosedAt == nil {
+		return time.Time{}
+	}
+	return *i.ClosedAt
+}
+
+// GetClosedBy returns the ClosedBy field.
+func (i *Issue) GetClosedBy() *User {
+	if i == nil {
+		return nil
+	}
+	return i.ClosedBy
+}
+
+// GetComments returns the Comments field if it's non-nil, zero value otherwise.
+func (i *Issue) GetComments() int {
+	if i == nil || i.Comments == nil {
+		return 0
+	}
+	return *i.Comments
+}
+
+// GetCommentsURL returns the CommentsURL field if it's non-nil, zero value otherwise.
+func (i *Issue) GetCommentsURL() string {
+	if i == nil || i.CommentsURL == nil {
+		return ""
+	}
+	return *i.CommentsURL
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (i *Issue) GetCreatedAt() time.Time {
+	if i == nil || i.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *i.CreatedAt
+}
+
+// GetEventsURL returns the EventsURL field if it's non-nil, zero value otherwise.
+func (i *Issue) GetEventsURL() string {
+	if i == nil || i.EventsURL == nil {
+		return ""
+	}
+	return *i.EventsURL
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (i *Issue) GetHTMLURL() string {
+	if i == nil || i.HTMLURL == nil {
+		return ""
+	}
+	return *i.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (i *Issue) GetID() int64 {
+	if i == nil || i.ID == nil {
+		return 0
+	}
+	return *i.ID
+}
+
+// GetLabelsURL returns the LabelsURL field if it's non-nil, zero value otherwise.
+func (i *Issue) GetLabelsURL() string {
+	if i == nil || i.LabelsURL == nil {
+		return ""
+	}
+	return *i.LabelsURL
+}
+
+// GetLocked returns the Locked field if it's non-nil, zero value otherwise.
+func (i *Issue) GetLocked() bool {
+	if i == nil || i.Locked == nil {
+		return false
+	}
+	return *i.Locked
+}
+
+// GetMilestone returns the Milestone field.
+func (i *Issue) GetMilestone() *Milestone {
+	if i == nil {
+		return nil
+	}
+	return i.Milestone
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (i *Issue) GetNodeID() string {
+	if i == nil || i.NodeID == nil {
+		return ""
+	}
+	return *i.NodeID
+}
+
+// GetNumber returns the Number field if it's non-nil, zero value otherwise.
+func (i *Issue) GetNumber() int {
+	if i == nil || i.Number == nil {
+		return 0
+	}
+	return *i.Number
+}
+
+// GetPullRequestLinks returns the PullRequestLinks field.
+func (i *Issue) GetPullRequestLinks() *PullRequestLinks {
+	if i == nil {
+		return nil
+	}
+	return i.PullRequestLinks
+}
+
+// GetReactions returns the Reactions field.
+func (i *Issue) GetReactions() *Reactions {
+	if i == nil {
+		return nil
+	}
+	return i.Reactions
+}
+
+// GetRepository returns the Repository field.
+func (i *Issue) GetRepository() *Repository {
+	if i == nil {
+		return nil
+	}
+	return i.Repository
+}
+
+// GetRepositoryURL returns the RepositoryURL field if it's non-nil, zero value otherwise.
+func (i *Issue) GetRepositoryURL() string {
+	if i == nil || i.RepositoryURL == nil {
+		return ""
+	}
+	return *i.RepositoryURL
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (i *Issue) GetState() string {
+	if i == nil || i.State == nil {
+		return ""
+	}
+	return *i.State
+}
+
+// GetTitle returns the Title field if it's non-nil, zero value otherwise.
+func (i *Issue) GetTitle() string {
+	if i == nil || i.Title == nil {
+		return ""
+	}
+	return *i.Title
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (i *Issue) GetUpdatedAt() time.Time {
+	if i == nil || i.UpdatedAt == nil {
+		return time.Time{}
+	}
+	return *i.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (i *Issue) GetURL() string {
+	if i == nil || i.URL == nil {
+		return ""
+	}
+	return *i.URL
+}
+
+// GetUser returns the User field.
+func (i *Issue) GetUser() *User {
+	if i == nil {
+		return nil
+	}
+	return i.User
+}
+
+// GetAuthorAssociation returns the AuthorAssociation field if it's non-nil, zero value otherwise.
+func (i *IssueComment) GetAuthorAssociation() string {
+	if i == nil || i.AuthorAssociation == nil {
+		return ""
+	}
+	return *i.AuthorAssociation
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (i *IssueComment) GetBody() string {
+	if i == nil || i.Body == nil {
+		return ""
+	}
+	return *i.Body
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (i *IssueComment) GetCreatedAt() time.Time {
+	if i == nil || i.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *i.CreatedAt
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (i *IssueComment) GetHTMLURL() string {
+	if i == nil || i.HTMLURL == nil {
+		return ""
+	}
+	return *i.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (i *IssueComment) GetID() int64 {
+	if i == nil || i.ID == nil {
+		return 0
+	}
+	return *i.ID
+}
+
+// GetIssueURL returns the IssueURL field if it's non-nil, zero value otherwise.
+func (i *IssueComment) GetIssueURL() string {
+	if i == nil || i.IssueURL == nil {
+		return ""
+	}
+	return *i.IssueURL
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (i *IssueComment) GetNodeID() string {
+	if i == nil || i.NodeID == nil {
+		return ""
+	}
+	return *i.NodeID
+}
+
+// GetReactions returns the Reactions field.
+func (i *IssueComment) GetReactions() *Reactions {
+	if i == nil {
+		return nil
+	}
+	return i.Reactions
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (i *IssueComment) GetUpdatedAt() time.Time {
+	if i == nil || i.UpdatedAt == nil {
+		return time.Time{}
+	}
+	return *i.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (i *IssueComment) GetURL() string {
+	if i == nil || i.URL == nil {
+		return ""
+	}
+	return *i.URL
+}
+
+// GetUser returns the User field.
+func (i *IssueComment) GetUser() *User {
+	if i == nil {
+		return nil
+	}
+	return i.User
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (i *IssueCommentEvent) GetAction() string {
+	if i == nil || i.Action == nil {
+		return ""
+	}
+	return *i.Action
+}
+
+// GetChanges returns the Changes field.
+func (i *IssueCommentEvent) GetChanges() *EditChange {
+	if i == nil {
+		return nil
+	}
+	return i.Changes
+}
+
+// GetComment returns the Comment field.
+func (i *IssueCommentEvent) GetComment() *IssueComment {
+	if i == nil {
+		return nil
+	}
+	return i.Comment
+}
+
+// GetInstallation returns the Installation field.
+func (i *IssueCommentEvent) GetInstallation() *Installation {
+	if i == nil {
+		return nil
+	}
+	return i.Installation
+}
+
+// GetIssue returns the Issue field.
+func (i *IssueCommentEvent) GetIssue() *Issue {
+	if i == nil {
+		return nil
+	}
+	return i.Issue
+}
+
+// GetRepo returns the Repo field.
+func (i *IssueCommentEvent) GetRepo() *Repository {
+	if i == nil {
+		return nil
+	}
+	return i.Repo
+}
+
+// GetSender returns the Sender field.
+func (i *IssueCommentEvent) GetSender() *User {
+	if i == nil {
+		return nil
+	}
+	return i.Sender
+}
+
+// GetActor returns the Actor field.
+func (i *IssueEvent) GetActor() *User {
+	if i == nil {
+		return nil
+	}
+	return i.Actor
+}
+
+// GetAssignee returns the Assignee field.
+func (i *IssueEvent) GetAssignee() *User {
+	if i == nil {
+		return nil
+	}
+	return i.Assignee
+}
+
+// GetAssigner returns the Assigner field.
+func (i *IssueEvent) GetAssigner() *User {
+	if i == nil {
+		return nil
+	}
+	return i.Assigner
+}
+
+// GetCommitID returns the CommitID field if it's non-nil, zero value otherwise.
+func (i *IssueEvent) GetCommitID() string {
+	if i == nil || i.CommitID == nil {
+		return ""
+	}
+	return *i.CommitID
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (i *IssueEvent) GetCreatedAt() time.Time {
+	if i == nil || i.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *i.CreatedAt
+}
+
+// GetEvent returns the Event field if it's non-nil, zero value otherwise.
+func (i *IssueEvent) GetEvent() string {
+	if i == nil || i.Event == nil {
+		return ""
+	}
+	return *i.Event
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (i *IssueEvent) GetID() int64 {
+	if i == nil || i.ID == nil {
+		return 0
+	}
+	return *i.ID
+}
+
+// GetIssue returns the Issue field.
+func (i *IssueEvent) GetIssue() *Issue {
+	if i == nil {
+		return nil
+	}
+	return i.Issue
+}
+
+// GetLabel returns the Label field.
+func (i *IssueEvent) GetLabel() *Label {
+	if i == nil {
+		return nil
+	}
+	return i.Label
+}
+
+// GetLockReason returns the LockReason field if it's non-nil, zero value otherwise.
+func (i *IssueEvent) GetLockReason() string {
+	if i == nil || i.LockReason == nil {
+		return ""
+	}
+	return *i.LockReason
+}
+
+// GetMilestone returns the Milestone field.
+func (i *IssueEvent) GetMilestone() *Milestone {
+	if i == nil {
+		return nil
+	}
+	return i.Milestone
+}
+
+// GetProjectCard returns the ProjectCard field.
+func (i *IssueEvent) GetProjectCard() *ProjectCard {
+	if i == nil {
+		return nil
+	}
+	return i.ProjectCard
+}
+
+// GetRename returns the Rename field.
+func (i *IssueEvent) GetRename() *Rename {
+	if i == nil {
+		return nil
+	}
+	return i.Rename
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (i *IssueEvent) GetURL() string {
+	if i == nil || i.URL == nil {
+		return ""
+	}
+	return *i.URL
+}
+
+// GetAssignee returns the Assignee field if it's non-nil, zero value otherwise.
+func (i *IssueRequest) GetAssignee() string {
+	if i == nil || i.Assignee == nil {
+		return ""
+	}
+	return *i.Assignee
+}
+
+// GetAssignees returns the Assignees field if it's non-nil, zero value otherwise.
+func (i *IssueRequest) GetAssignees() []string {
+	if i == nil || i.Assignees == nil {
+		return nil
+	}
+	return *i.Assignees
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (i *IssueRequest) GetBody() string {
+	if i == nil || i.Body == nil {
+		return ""
+	}
+	return *i.Body
+}
+
+// GetLabels returns the Labels field if it's non-nil, zero value otherwise.
+func (i *IssueRequest) GetLabels() []string {
+	if i == nil || i.Labels == nil {
+		return nil
+	}
+	return *i.Labels
+}
+
+// GetMilestone returns the Milestone field if it's non-nil, zero value otherwise.
+func (i *IssueRequest) GetMilestone() int {
+	if i == nil || i.Milestone == nil {
+		return 0
+	}
+	return *i.Milestone
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (i *IssueRequest) GetState() string {
+	if i == nil || i.State == nil {
+		return ""
+	}
+	return *i.State
+}
+
+// GetTitle returns the Title field if it's non-nil, zero value otherwise.
+func (i *IssueRequest) GetTitle() string {
+	if i == nil || i.Title == nil {
+		return ""
+	}
+	return *i.Title
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (i *IssuesEvent) GetAction() string {
+	if i == nil || i.Action == nil {
+		return ""
+	}
+	return *i.Action
+}
+
+// GetAssignee returns the Assignee field.
+func (i *IssuesEvent) GetAssignee() *User {
+	if i == nil {
+		return nil
+	}
+	return i.Assignee
+}
+
+// GetChanges returns the Changes field.
+func (i *IssuesEvent) GetChanges() *EditChange {
+	if i == nil {
+		return nil
+	}
+	return i.Changes
+}
+
+// GetInstallation returns the Installation field.
+func (i *IssuesEvent) GetInstallation() *Installation {
+	if i == nil {
+		return nil
+	}
+	return i.Installation
+}
+
+// GetIssue returns the Issue field.
+func (i *IssuesEvent) GetIssue() *Issue {
+	if i == nil {
+		return nil
+	}
+	return i.Issue
+}
+
+// GetLabel returns the Label field.
+func (i *IssuesEvent) GetLabel() *Label {
+	if i == nil {
+		return nil
+	}
+	return i.Label
+}
+
+// GetRepo returns the Repo field.
+func (i *IssuesEvent) GetRepo() *Repository {
+	if i == nil {
+		return nil
+	}
+	return i.Repo
+}
+
+// GetSender returns the Sender field.
+func (i *IssuesEvent) GetSender() *User {
+	if i == nil {
+		return nil
+	}
+	return i.Sender
+}
+
+// GetIncompleteResults returns the IncompleteResults field if it's non-nil, zero value otherwise.
+func (i *IssuesSearchResult) GetIncompleteResults() bool {
+	if i == nil || i.IncompleteResults == nil {
+		return false
+	}
+	return *i.IncompleteResults
+}
+
+// GetTotal returns the Total field if it's non-nil, zero value otherwise.
+func (i *IssuesSearchResult) GetTotal() int {
+	if i == nil || i.Total == nil {
+		return 0
+	}
+	return *i.Total
+}
+
+// GetClosedIssues returns the ClosedIssues field if it's non-nil, zero value otherwise.
+func (i *IssueStats) GetClosedIssues() int {
+	if i == nil || i.ClosedIssues == nil {
+		return 0
+	}
+	return *i.ClosedIssues
+}
+
+// GetOpenIssues returns the OpenIssues field if it's non-nil, zero value otherwise.
+func (i *IssueStats) GetOpenIssues() int {
+	if i == nil || i.OpenIssues == nil {
+		return 0
+	}
+	return *i.OpenIssues
+}
+
+// GetTotalIssues returns the TotalIssues field if it's non-nil, zero value otherwise.
+func (i *IssueStats) GetTotalIssues() int {
+	if i == nil || i.TotalIssues == nil {
+		return 0
+	}
+	return *i.TotalIssues
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (k *Key) GetID() int64 {
+	if k == nil || k.ID == nil {
+		return 0
+	}
+	return *k.ID
+}
+
+// GetKey returns the Key field if it's non-nil, zero value otherwise.
+func (k *Key) GetKey() string {
+	if k == nil || k.Key == nil {
+		return ""
+	}
+	return *k.Key
+}
+
+// GetReadOnly returns the ReadOnly field if it's non-nil, zero value otherwise.
+func (k *Key) GetReadOnly() bool {
+	if k == nil || k.ReadOnly == nil {
+		return false
+	}
+	return *k.ReadOnly
+}
+
+// GetTitle returns the Title field if it's non-nil, zero value otherwise.
+func (k *Key) GetTitle() string {
+	if k == nil || k.Title == nil {
+		return ""
+	}
+	return *k.Title
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (k *Key) GetURL() string {
+	if k == nil || k.URL == nil {
+		return ""
+	}
+	return *k.URL
+}
+
+// GetColor returns the Color field if it's non-nil, zero value otherwise.
+func (l *Label) GetColor() string {
+	if l == nil || l.Color == nil {
+		return ""
+	}
+	return *l.Color
+}
+
+// GetDefault returns the Default field if it's non-nil, zero value otherwise.
+func (l *Label) GetDefault() bool {
+	if l == nil || l.Default == nil {
+		return false
+	}
+	return *l.Default
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (l *Label) GetDescription() string {
+	if l == nil || l.Description == nil {
+		return ""
+	}
+	return *l.Description
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (l *Label) GetID() int64 {
+	if l == nil || l.ID == nil {
+		return 0
+	}
+	return *l.ID
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (l *Label) GetName() string {
+	if l == nil || l.Name == nil {
+		return ""
+	}
+	return *l.Name
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (l *Label) GetNodeID() string {
+	if l == nil || l.NodeID == nil {
+		return ""
+	}
+	return *l.NodeID
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (l *Label) GetURL() string {
+	if l == nil || l.URL == nil {
+		return ""
+	}
+	return *l.URL
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (l *LabelEvent) GetAction() string {
+	if l == nil || l.Action == nil {
+		return ""
+	}
+	return *l.Action
+}
+
+// GetChanges returns the Changes field.
+func (l *LabelEvent) GetChanges() *EditChange {
+	if l == nil {
+		return nil
+	}
+	return l.Changes
+}
+
+// GetInstallation returns the Installation field.
+func (l *LabelEvent) GetInstallation() *Installation {
+	if l == nil {
+		return nil
+	}
+	return l.Installation
+}
+
+// GetLabel returns the Label field.
+func (l *LabelEvent) GetLabel() *Label {
+	if l == nil {
+		return nil
+	}
+	return l.Label
+}
+
+// GetOrg returns the Org field.
+func (l *LabelEvent) GetOrg() *Organization {
+	if l == nil {
+		return nil
+	}
+	return l.Org
+}
+
+// GetRepo returns the Repo field.
+func (l *LabelEvent) GetRepo() *Repository {
+	if l == nil {
+		return nil
+	}
+	return l.Repo
+}
+
+// GetColor returns the Color field if it's non-nil, zero value otherwise.
+func (l *LabelResult) GetColor() string {
+	if l == nil || l.Color == nil {
+		return ""
+	}
+	return *l.Color
+}
+
+// GetDefault returns the Default field if it's non-nil, zero value otherwise.
+func (l *LabelResult) GetDefault() bool {
+	if l == nil || l.Default == nil {
+		return false
+	}
+	return *l.Default
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (l *LabelResult) GetDescription() string {
+	if l == nil || l.Description == nil {
+		return ""
+	}
+	return *l.Description
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (l *LabelResult) GetID() int64 {
+	if l == nil || l.ID == nil {
+		return 0
+	}
+	return *l.ID
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (l *LabelResult) GetName() string {
+	if l == nil || l.Name == nil {
+		return ""
+	}
+	return *l.Name
+}
+
+// GetScore returns the Score field.
+func (l *LabelResult) GetScore() *float64 {
+	if l == nil {
+		return nil
+	}
+	return l.Score
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (l *LabelResult) GetURL() string {
+	if l == nil || l.URL == nil {
+		return ""
+	}
+	return *l.URL
+}
+
+// GetIncompleteResults returns the IncompleteResults field if it's non-nil, zero value otherwise.
+func (l *LabelsSearchResult) GetIncompleteResults() bool {
+	if l == nil || l.IncompleteResults == nil {
+		return false
+	}
+	return *l.IncompleteResults
+}
+
+// GetTotal returns the Total field if it's non-nil, zero value otherwise.
+func (l *LabelsSearchResult) GetTotal() int {
+	if l == nil || l.Total == nil {
+		return 0
+	}
+	return *l.Total
+}
+
+// GetOID returns the OID field if it's non-nil, zero value otherwise.
+func (l *LargeFile) GetOID() string {
+	if l == nil || l.OID == nil {
+		return ""
+	}
+	return *l.OID
+}
+
+// GetPath returns the Path field if it's non-nil, zero value otherwise.
+func (l *LargeFile) GetPath() string {
+	if l == nil || l.Path == nil {
+		return ""
+	}
+	return *l.Path
+}
+
+// GetRefName returns the RefName field if it's non-nil, zero value otherwise.
+func (l *LargeFile) GetRefName() string {
+	if l == nil || l.RefName == nil {
+		return ""
+	}
+	return *l.RefName
+}
+
+// GetSize returns the Size field if it's non-nil, zero value otherwise.
+func (l *LargeFile) GetSize() int {
+	if l == nil || l.Size == nil {
+		return 0
+	}
+	return *l.Size
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (l *License) GetBody() string {
+	if l == nil || l.Body == nil {
+		return ""
+	}
+	return *l.Body
+}
+
+// GetConditions returns the Conditions field if it's non-nil, zero value otherwise.
+func (l *License) GetConditions() []string {
+	if l == nil || l.Conditions == nil {
+		return nil
+	}
+	return *l.Conditions
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (l *License) GetDescription() string {
+	if l == nil || l.Description == nil {
+		return ""
+	}
+	return *l.Description
+}
+
+// GetFeatured returns the Featured field if it's non-nil, zero value otherwise.
+func (l *License) GetFeatured() bool {
+	if l == nil || l.Featured == nil {
+		return false
+	}
+	return *l.Featured
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (l *License) GetHTMLURL() string {
+	if l == nil || l.HTMLURL == nil {
+		return ""
+	}
+	return *l.HTMLURL
+}
+
+// GetImplementation returns the Implementation field if it's non-nil, zero value otherwise.
+func (l *License) GetImplementation() string {
+	if l == nil || l.Implementation == nil {
+		return ""
+	}
+	return *l.Implementation
+}
+
+// GetKey returns the Key field if it's non-nil, zero value otherwise.
+func (l *License) GetKey() string {
+	if l == nil || l.Key == nil {
+		return ""
+	}
+	return *l.Key
+}
+
+// GetLimitations returns the Limitations field if it's non-nil, zero value otherwise.
+func (l *License) GetLimitations() []string {
+	if l == nil || l.Limitations == nil {
+		return nil
+	}
+	return *l.Limitations
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (l *License) GetName() string {
+	if l == nil || l.Name == nil {
+		return ""
+	}
+	return *l.Name
+}
+
+// GetPermissions returns the Permissions field if it's non-nil, zero value otherwise.
+func (l *License) GetPermissions() []string {
+	if l == nil || l.Permissions == nil {
+		return nil
+	}
+	return *l.Permissions
+}
+
+// GetSPDXID returns the SPDXID field if it's non-nil, zero value otherwise.
+func (l *License) GetSPDXID() string {
+	if l == nil || l.SPDXID == nil {
+		return ""
+	}
+	return *l.SPDXID
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (l *License) GetURL() string {
+	if l == nil || l.URL == nil {
+		return ""
+	}
+	return *l.URL
+}
+
+// GetCheckName returns the CheckName field if it's non-nil, zero value otherwise.
+func (l *ListCheckRunsOptions) GetCheckName() string {
+	if l == nil || l.CheckName == nil {
+		return ""
+	}
+	return *l.CheckName
+}
+
+// GetFilter returns the Filter field if it's non-nil, zero value otherwise.
+func (l *ListCheckRunsOptions) GetFilter() string {
+	if l == nil || l.Filter == nil {
+		return ""
+	}
+	return *l.Filter
+}
+
+// GetStatus returns the Status field if it's non-nil, zero value otherwise.
+func (l *ListCheckRunsOptions) GetStatus() string {
+	if l == nil || l.Status == nil {
+		return ""
+	}
+	return *l.Status
+}
+
+// GetTotal returns the Total field if it's non-nil, zero value otherwise.
+func (l *ListCheckRunsResults) GetTotal() int {
+	if l == nil || l.Total == nil {
+		return 0
+	}
+	return *l.Total
+}
+
+// GetAppID returns the AppID field if it's non-nil, zero value otherwise.
+func (l *ListCheckSuiteOptions) GetAppID() int {
+	if l == nil || l.AppID == nil {
+		return 0
+	}
+	return *l.AppID
+}
+
+// GetCheckName returns the CheckName field if it's non-nil, zero value otherwise.
+func (l *ListCheckSuiteOptions) GetCheckName() string {
+	if l == nil || l.CheckName == nil {
+		return ""
+	}
+	return *l.CheckName
+}
+
+// GetTotal returns the Total field if it's non-nil, zero value otherwise.
+func (l *ListCheckSuiteResults) GetTotal() int {
+	if l == nil || l.Total == nil {
+		return 0
+	}
+	return *l.Total
+}
+
+// GetAffiliation returns the Affiliation field if it's non-nil, zero value otherwise.
+func (l *ListCollaboratorOptions) GetAffiliation() string {
+	if l == nil || l.Affiliation == nil {
+		return ""
+	}
+	return *l.Affiliation
+}
+
+// GetEffectiveDate returns the EffectiveDate field if it's non-nil, zero value otherwise.
+func (m *MarketplacePendingChange) GetEffectiveDate() Timestamp {
+	if m == nil || m.EffectiveDate == nil {
+		return Timestamp{}
+	}
+	return *m.EffectiveDate
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (m *MarketplacePendingChange) GetID() int64 {
+	if m == nil || m.ID == nil {
+		return 0
+	}
+	return *m.ID
+}
+
+// GetPlan returns the Plan field.
+func (m *MarketplacePendingChange) GetPlan() *MarketplacePlan {
+	if m == nil {
+		return nil
+	}
+	return m.Plan
+}
+
+// GetUnitCount returns the UnitCount field if it's non-nil, zero value otherwise.
+func (m *MarketplacePendingChange) GetUnitCount() int {
+	if m == nil || m.UnitCount == nil {
+		return 0
+	}
+	return *m.UnitCount
+}
+
+// GetAccountsURL returns the AccountsURL field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlan) GetAccountsURL() string {
+	if m == nil || m.AccountsURL == nil {
+		return ""
+	}
+	return *m.AccountsURL
+}
+
+// GetBullets returns the Bullets field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlan) GetBullets() []string {
+	if m == nil || m.Bullets == nil {
+		return nil
+	}
+	return *m.Bullets
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlan) GetDescription() string {
+	if m == nil || m.Description == nil {
+		return ""
+	}
+	return *m.Description
+}
+
+// GetHasFreeTrial returns the HasFreeTrial field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlan) GetHasFreeTrial() bool {
+	if m == nil || m.HasFreeTrial == nil {
+		return false
+	}
+	return *m.HasFreeTrial
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlan) GetID() int64 {
+	if m == nil || m.ID == nil {
+		return 0
+	}
+	return *m.ID
+}
+
+// GetMonthlyPriceInCents returns the MonthlyPriceInCents field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlan) GetMonthlyPriceInCents() int {
+	if m == nil || m.MonthlyPriceInCents == nil {
+		return 0
+	}
+	return *m.MonthlyPriceInCents
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlan) GetName() string {
+	if m == nil || m.Name == nil {
+		return ""
+	}
+	return *m.Name
+}
+
+// GetPriceModel returns the PriceModel field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlan) GetPriceModel() string {
+	if m == nil || m.PriceModel == nil {
+		return ""
+	}
+	return *m.PriceModel
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlan) GetState() string {
+	if m == nil || m.State == nil {
+		return ""
+	}
+	return *m.State
+}
+
+// GetUnitName returns the UnitName field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlan) GetUnitName() string {
+	if m == nil || m.UnitName == nil {
+		return ""
+	}
+	return *m.UnitName
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlan) GetURL() string {
+	if m == nil || m.URL == nil {
+		return ""
+	}
+	return *m.URL
+}
+
+// GetYearlyPriceInCents returns the YearlyPriceInCents field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlan) GetYearlyPriceInCents() int {
+	if m == nil || m.YearlyPriceInCents == nil {
+		return 0
+	}
+	return *m.YearlyPriceInCents
+}
+
+// GetEmail returns the Email field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlanAccount) GetEmail() string {
+	if m == nil || m.Email == nil {
+		return ""
+	}
+	return *m.Email
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlanAccount) GetID() int64 {
+	if m == nil || m.ID == nil {
+		return 0
+	}
+	return *m.ID
+}
+
+// GetLogin returns the Login field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlanAccount) GetLogin() string {
+	if m == nil || m.Login == nil {
+		return ""
+	}
+	return *m.Login
+}
+
+// GetMarketplacePendingChange returns the MarketplacePendingChange field.
+func (m *MarketplacePlanAccount) GetMarketplacePendingChange() *MarketplacePendingChange {
+	if m == nil {
+		return nil
+	}
+	return m.MarketplacePendingChange
+}
+
+// GetMarketplacePurchase returns the MarketplacePurchase field.
+func (m *MarketplacePlanAccount) GetMarketplacePurchase() *MarketplacePurchase {
+	if m == nil {
+		return nil
+	}
+	return m.MarketplacePurchase
+}
+
+// GetOrganizationBillingEmail returns the OrganizationBillingEmail field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlanAccount) GetOrganizationBillingEmail() string {
+	if m == nil || m.OrganizationBillingEmail == nil {
+		return ""
+	}
+	return *m.OrganizationBillingEmail
+}
+
+// GetType returns the Type field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlanAccount) GetType() string {
+	if m == nil || m.Type == nil {
+		return ""
+	}
+	return *m.Type
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlanAccount) GetURL() string {
+	if m == nil || m.URL == nil {
+		return ""
+	}
+	return *m.URL
+}
+
+// GetAccount returns the Account field.
+func (m *MarketplacePurchase) GetAccount() *MarketplacePlanAccount {
+	if m == nil {
+		return nil
+	}
+	return m.Account
+}
+
+// GetBillingCycle returns the BillingCycle field if it's non-nil, zero value otherwise.
+func (m *MarketplacePurchase) GetBillingCycle() string {
+	if m == nil || m.BillingCycle == nil {
+		return ""
+	}
+	return *m.BillingCycle
+}
+
+// GetFreeTrialEndsOn returns the FreeTrialEndsOn field if it's non-nil, zero value otherwise.
+func (m *MarketplacePurchase) GetFreeTrialEndsOn() Timestamp {
+	if m == nil || m.FreeTrialEndsOn == nil {
+		return Timestamp{}
+	}
+	return *m.FreeTrialEndsOn
+}
+
+// GetNextBillingDate returns the NextBillingDate field if it's non-nil, zero value otherwise.
+func (m *MarketplacePurchase) GetNextBillingDate() Timestamp {
+	if m == nil || m.NextBillingDate == nil {
+		return Timestamp{}
+	}
+	return *m.NextBillingDate
+}
+
+// GetOnFreeTrial returns the OnFreeTrial field if it's non-nil, zero value otherwise.
+func (m *MarketplacePurchase) GetOnFreeTrial() bool {
+	if m == nil || m.OnFreeTrial == nil {
+		return false
+	}
+	return *m.OnFreeTrial
+}
+
+// GetPlan returns the Plan field.
+func (m *MarketplacePurchase) GetPlan() *MarketplacePlan {
+	if m == nil {
+		return nil
+	}
+	return m.Plan
+}
+
+// GetUnitCount returns the UnitCount field if it's non-nil, zero value otherwise.
+func (m *MarketplacePurchase) GetUnitCount() int {
+	if m == nil || m.UnitCount == nil {
+		return 0
+	}
+	return *m.UnitCount
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (m *MarketplacePurchaseEvent) GetAction() string {
+	if m == nil || m.Action == nil {
+		return ""
+	}
+	return *m.Action
+}
+
+// GetEffectiveDate returns the EffectiveDate field if it's non-nil, zero value otherwise.
+func (m *MarketplacePurchaseEvent) GetEffectiveDate() Timestamp {
+	if m == nil || m.EffectiveDate == nil {
+		return Timestamp{}
+	}
+	return *m.EffectiveDate
+}
+
+// GetInstallation returns the Installation field.
+func (m *MarketplacePurchaseEvent) GetInstallation() *Installation {
+	if m == nil {
+		return nil
+	}
+	return m.Installation
+}
+
+// GetMarketplacePurchase returns the MarketplacePurchase field.
+func (m *MarketplacePurchaseEvent) GetMarketplacePurchase() *MarketplacePurchase {
+	if m == nil {
+		return nil
+	}
+	return m.MarketplacePurchase
+}
+
+// GetPreviousMarketplacePurchase returns the PreviousMarketplacePurchase field.
+func (m *MarketplacePurchaseEvent) GetPreviousMarketplacePurchase() *MarketplacePurchase {
+	if m == nil {
+		return nil
+	}
+	return m.PreviousMarketplacePurchase
+}
+
+// GetSender returns the Sender field.
+func (m *MarketplacePurchaseEvent) GetSender() *User {
+	if m == nil {
+		return nil
+	}
+	return m.Sender
+}
+
+// GetText returns the Text field if it's non-nil, zero value otherwise.
+func (m *Match) GetText() string {
+	if m == nil || m.Text == nil {
+		return ""
+	}
+	return *m.Text
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (m *MemberEvent) GetAction() string {
+	if m == nil || m.Action == nil {
+		return ""
+	}
+	return *m.Action
+}
+
+// GetInstallation returns the Installation field.
+func (m *MemberEvent) GetInstallation() *Installation {
+	if m == nil {
+		return nil
+	}
+	return m.Installation
+}
+
+// GetMember returns the Member field.
+func (m *MemberEvent) GetMember() *User {
+	if m == nil {
+		return nil
+	}
+	return m.Member
+}
+
+// GetRepo returns the Repo field.
+func (m *MemberEvent) GetRepo() *Repository {
+	if m == nil {
+		return nil
+	}
+	return m.Repo
+}
+
+// GetSender returns the Sender field.
+func (m *MemberEvent) GetSender() *User {
+	if m == nil {
+		return nil
+	}
+	return m.Sender
+}
+
+// GetOrganization returns the Organization field.
+func (m *Membership) GetOrganization() *Organization {
+	if m == nil {
+		return nil
+	}
+	return m.Organization
+}
+
+// GetOrganizationURL returns the OrganizationURL field if it's non-nil, zero value otherwise.
+func (m *Membership) GetOrganizationURL() string {
+	if m == nil || m.OrganizationURL == nil {
+		return ""
+	}
+	return *m.OrganizationURL
+}
+
+// GetRole returns the Role field if it's non-nil, zero value otherwise.
+func (m *Membership) GetRole() string {
+	if m == nil || m.Role == nil {
+		return ""
+	}
+	return *m.Role
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (m *Membership) GetState() string {
+	if m == nil || m.State == nil {
+		return ""
+	}
+	return *m.State
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (m *Membership) GetURL() string {
+	if m == nil || m.URL == nil {
+		return ""
+	}
+	return *m.URL
+}
+
+// GetUser returns the User field.
+func (m *Membership) GetUser() *User {
+	if m == nil {
+		return nil
+	}
+	return m.User
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (m *MembershipEvent) GetAction() string {
+	if m == nil || m.Action == nil {
+		return ""
+	}
+	return *m.Action
+}
+
+// GetInstallation returns the Installation field.
+func (m *MembershipEvent) GetInstallation() *Installation {
+	if m == nil {
+		return nil
+	}
+	return m.Installation
+}
+
+// GetMember returns the Member field.
+func (m *MembershipEvent) GetMember() *User {
+	if m == nil {
+		return nil
+	}
+	return m.Member
+}
+
+// GetOrg returns the Org field.
+func (m *MembershipEvent) GetOrg() *Organization {
+	if m == nil {
+		return nil
+	}
+	return m.Org
+}
+
+// GetScope returns the Scope field if it's non-nil, zero value otherwise.
+func (m *MembershipEvent) GetScope() string {
+	if m == nil || m.Scope == nil {
+		return ""
+	}
+	return *m.Scope
+}
+
+// GetSender returns the Sender field.
+func (m *MembershipEvent) GetSender() *User {
+	if m == nil {
+		return nil
+	}
+	return m.Sender
+}
+
+// GetTeam returns the Team field.
+func (m *MembershipEvent) GetTeam() *Team {
+	if m == nil {
+		return nil
+	}
+	return m.Team
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (m *Metric) GetHTMLURL() string {
+	if m == nil || m.HTMLURL == nil {
+		return ""
+	}
+	return *m.HTMLURL
+}
+
+// GetKey returns the Key field if it's non-nil, zero value otherwise.
+func (m *Metric) GetKey() string {
+	if m == nil || m.Key == nil {
+		return ""
+	}
+	return *m.Key
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (m *Metric) GetName() string {
+	if m == nil || m.Name == nil {
+		return ""
+	}
+	return *m.Name
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (m *Metric) GetURL() string {
+	if m == nil || m.URL == nil {
+		return ""
+	}
+	return *m.URL
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (m *Migration) GetCreatedAt() string {
+	if m == nil || m.CreatedAt == nil {
+		return ""
+	}
+	return *m.CreatedAt
+}
+
+// GetExcludeAttachments returns the ExcludeAttachments field if it's non-nil, zero value otherwise.
+func (m *Migration) GetExcludeAttachments() bool {
+	if m == nil || m.ExcludeAttachments == nil {
+		return false
+	}
+	return *m.ExcludeAttachments
+}
+
+// GetGUID returns the GUID field if it's non-nil, zero value otherwise.
+func (m *Migration) GetGUID() string {
+	if m == nil || m.GUID == nil {
+		return ""
+	}
+	return *m.GUID
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (m *Migration) GetID() int64 {
+	if m == nil || m.ID == nil {
+		return 0
+	}
+	return *m.ID
+}
+
+// GetLockRepositories returns the LockRepositories field if it's non-nil, zero value otherwise.
+func (m *Migration) GetLockRepositories() bool {
+	if m == nil || m.LockRepositories == nil {
+		return false
+	}
+	return *m.LockRepositories
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (m *Migration) GetState() string {
+	if m == nil || m.State == nil {
+		return ""
+	}
+	return *m.State
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (m *Migration) GetUpdatedAt() string {
+	if m == nil || m.UpdatedAt == nil {
+		return ""
+	}
+	return *m.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (m *Migration) GetURL() string {
+	if m == nil || m.URL == nil {
+		return ""
+	}
+	return *m.URL
+}
+
+// GetClosedAt returns the ClosedAt field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetClosedAt() time.Time {
+	if m == nil || m.ClosedAt == nil {
+		return time.Time{}
+	}
+	return *m.ClosedAt
+}
+
+// GetClosedIssues returns the ClosedIssues field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetClosedIssues() int {
+	if m == nil || m.ClosedIssues == nil {
+		return 0
+	}
+	return *m.ClosedIssues
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetCreatedAt() time.Time {
+	if m == nil || m.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *m.CreatedAt
+}
+
+// GetCreator returns the Creator field.
+func (m *Milestone) GetCreator() *User {
+	if m == nil {
+		return nil
+	}
+	return m.Creator
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetDescription() string {
+	if m == nil || m.Description == nil {
+		return ""
+	}
+	return *m.Description
+}
+
+// GetDueOn returns the DueOn field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetDueOn() time.Time {
+	if m == nil || m.DueOn == nil {
+		return time.Time{}
+	}
+	return *m.DueOn
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetHTMLURL() string {
+	if m == nil || m.HTMLURL == nil {
+		return ""
+	}
+	return *m.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetID() int64 {
+	if m == nil || m.ID == nil {
+		return 0
+	}
+	return *m.ID
+}
+
+// GetLabelsURL returns the LabelsURL field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetLabelsURL() string {
+	if m == nil || m.LabelsURL == nil {
+		return ""
+	}
+	return *m.LabelsURL
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetNodeID() string {
+	if m == nil || m.NodeID == nil {
+		return ""
+	}
+	return *m.NodeID
+}
+
+// GetNumber returns the Number field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetNumber() int {
+	if m == nil || m.Number == nil {
+		return 0
+	}
+	return *m.Number
+}
+
+// GetOpenIssues returns the OpenIssues field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetOpenIssues() int {
+	if m == nil || m.OpenIssues == nil {
+		return 0
+	}
+	return *m.OpenIssues
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetState() string {
+	if m == nil || m.State == nil {
+		return ""
+	}
+	return *m.State
+}
+
+// GetTitle returns the Title field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetTitle() string {
+	if m == nil || m.Title == nil {
+		return ""
+	}
+	return *m.Title
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetUpdatedAt() time.Time {
+	if m == nil || m.UpdatedAt == nil {
+		return time.Time{}
+	}
+	return *m.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetURL() string {
+	if m == nil || m.URL == nil {
+		return ""
+	}
+	return *m.URL
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (m *MilestoneEvent) GetAction() string {
+	if m == nil || m.Action == nil {
+		return ""
+	}
+	return *m.Action
+}
+
+// GetChanges returns the Changes field.
+func (m *MilestoneEvent) GetChanges() *EditChange {
+	if m == nil {
+		return nil
+	}
+	return m.Changes
+}
+
+// GetInstallation returns the Installation field.
+func (m *MilestoneEvent) GetInstallation() *Installation {
+	if m == nil {
+		return nil
+	}
+	return m.Installation
+}
+
+// GetMilestone returns the Milestone field.
+func (m *MilestoneEvent) GetMilestone() *Milestone {
+	if m == nil {
+		return nil
+	}
+	return m.Milestone
+}
+
+// GetOrg returns the Org field.
+func (m *MilestoneEvent) GetOrg() *Organization {
+	if m == nil {
+		return nil
+	}
+	return m.Org
+}
+
+// GetRepo returns the Repo field.
+func (m *MilestoneEvent) GetRepo() *Repository {
+	if m == nil {
+		return nil
+	}
+	return m.Repo
+}
+
+// GetSender returns the Sender field.
+func (m *MilestoneEvent) GetSender() *User {
+	if m == nil {
+		return nil
+	}
+	return m.Sender
+}
+
+// GetClosedMilestones returns the ClosedMilestones field if it's non-nil, zero value otherwise.
+func (m *MilestoneStats) GetClosedMilestones() int {
+	if m == nil || m.ClosedMilestones == nil {
+		return 0
+	}
+	return *m.ClosedMilestones
+}
+
+// GetOpenMilestones returns the OpenMilestones field if it's non-nil, zero value otherwise.
+func (m *MilestoneStats) GetOpenMilestones() int {
+	if m == nil || m.OpenMilestones == nil {
+		return 0
+	}
+	return *m.OpenMilestones
+}
+
+// GetTotalMilestones returns the TotalMilestones field if it's non-nil, zero value otherwise.
+func (m *MilestoneStats) GetTotalMilestones() int {
+	if m == nil || m.TotalMilestones == nil {
+		return 0
+	}
+	return *m.TotalMilestones
+}
+
+// GetBase returns the Base field if it's non-nil, zero value otherwise.
+func (n *NewPullRequest) GetBase() string {
+	if n == nil || n.Base == nil {
+		return ""
+	}
+	return *n.Base
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (n *NewPullRequest) GetBody() string {
+	if n == nil || n.Body == nil {
+		return ""
+	}
+	return *n.Body
+}
+
+// GetHead returns the Head field if it's non-nil, zero value otherwise.
+func (n *NewPullRequest) GetHead() string {
+	if n == nil || n.Head == nil {
+		return ""
+	}
+	return *n.Head
+}
+
+// GetIssue returns the Issue field if it's non-nil, zero value otherwise.
+func (n *NewPullRequest) GetIssue() int {
+	if n == nil || n.Issue == nil {
+		return 0
+	}
+	return *n.Issue
+}
+
+// GetMaintainerCanModify returns the MaintainerCanModify field if it's non-nil, zero value otherwise.
+func (n *NewPullRequest) GetMaintainerCanModify() bool {
+	if n == nil || n.MaintainerCanModify == nil {
+		return false
+	}
+	return *n.MaintainerCanModify
+}
+
+// GetTitle returns the Title field if it's non-nil, zero value otherwise.
+func (n *NewPullRequest) GetTitle() string {
+	if n == nil || n.Title == nil {
+		return ""
+	}
+	return *n.Title
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (n *NewTeam) GetDescription() string {
+	if n == nil || n.Description == nil {
+		return ""
+	}
+	return *n.Description
+}
+
+// GetLDAPDN returns the LDAPDN field if it's non-nil, zero value otherwise.
+func (n *NewTeam) GetLDAPDN() string {
+	if n == nil || n.LDAPDN == nil {
+		return ""
+	}
+	return *n.LDAPDN
+}
+
+// GetParentTeamID returns the ParentTeamID field if it's non-nil, zero value otherwise.
+func (n *NewTeam) GetParentTeamID() int64 {
+	if n == nil || n.ParentTeamID == nil {
+		return 0
+	}
+	return *n.ParentTeamID
+}
+
+// GetPermission returns the Permission field if it's non-nil, zero value otherwise.
+func (n *NewTeam) GetPermission() string {
+	if n == nil || n.Permission == nil {
+		return ""
+	}
+	return *n.Permission
+}
+
+// GetPrivacy returns the Privacy field if it's non-nil, zero value otherwise.
+func (n *NewTeam) GetPrivacy() string {
+	if n == nil || n.Privacy == nil {
+		return ""
+	}
+	return *n.Privacy
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (n *Notification) GetID() string {
+	if n == nil || n.ID == nil {
+		return ""
+	}
+	return *n.ID
+}
+
+// GetLastReadAt returns the LastReadAt field if it's non-nil, zero value otherwise.
+func (n *Notification) GetLastReadAt() time.Time {
+	if n == nil || n.LastReadAt == nil {
+		return time.Time{}
+	}
+	return *n.LastReadAt
+}
+
+// GetReason returns the Reason field if it's non-nil, zero value otherwise.
+func (n *Notification) GetReason() string {
+	if n == nil || n.Reason == nil {
+		return ""
+	}
+	return *n.Reason
+}
+
+// GetRepository returns the Repository field.
+func (n *Notification) GetRepository() *Repository {
+	if n == nil {
+		return nil
+	}
+	return n.Repository
+}
+
+// GetSubject returns the Subject field.
+func (n *Notification) GetSubject() *NotificationSubject {
+	if n == nil {
+		return nil
+	}
+	return n.Subject
+}
+
+// GetUnread returns the Unread field if it's non-nil, zero value otherwise.
+func (n *Notification) GetUnread() bool {
+	if n == nil || n.Unread == nil {
+		return false
+	}
+	return *n.Unread
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (n *Notification) GetUpdatedAt() time.Time {
+	if n == nil || n.UpdatedAt == nil {
+		return time.Time{}
+	}
+	return *n.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (n *Notification) GetURL() string {
+	if n == nil || n.URL == nil {
+		return ""
+	}
+	return *n.URL
+}
+
+// GetLatestCommentURL returns the LatestCommentURL field if it's non-nil, zero value otherwise.
+func (n *NotificationSubject) GetLatestCommentURL() string {
+	if n == nil || n.LatestCommentURL == nil {
+		return ""
+	}
+	return *n.LatestCommentURL
+}
+
+// GetTitle returns the Title field if it's non-nil, zero value otherwise.
+func (n *NotificationSubject) GetTitle() string {
+	if n == nil || n.Title == nil {
+		return ""
+	}
+	return *n.Title
+}
+
+// GetType returns the Type field if it's non-nil, zero value otherwise.
+func (n *NotificationSubject) GetType() string {
+	if n == nil || n.Type == nil {
+		return ""
+	}
+	return *n.Type
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (n *NotificationSubject) GetURL() string {
+	if n == nil || n.URL == nil {
+		return ""
+	}
+	return *n.URL
+}
+
+// GetAvatarURL returns the AvatarURL field if it's non-nil, zero value otherwise.
+func (o *Organization) GetAvatarURL() string {
+	if o == nil || o.AvatarURL == nil {
+		return ""
+	}
+	return *o.AvatarURL
+}
+
+// GetBillingEmail returns the BillingEmail field if it's non-nil, zero value otherwise.
+func (o *Organization) GetBillingEmail() string {
+	if o == nil || o.BillingEmail == nil {
+		return ""
+	}
+	return *o.BillingEmail
+}
+
+// GetBlog returns the Blog field if it's non-nil, zero value otherwise.
+func (o *Organization) GetBlog() string {
+	if o == nil || o.Blog == nil {
+		return ""
+	}
+	return *o.Blog
+}
+
+// GetCollaborators returns the Collaborators field if it's non-nil, zero value otherwise.
+func (o *Organization) GetCollaborators() int {
+	if o == nil || o.Collaborators == nil {
+		return 0
+	}
+	return *o.Collaborators
+}
+
+// GetCompany returns the Company field if it's non-nil, zero value otherwise.
+func (o *Organization) GetCompany() string {
+	if o == nil || o.Company == nil {
+		return ""
+	}
+	return *o.Company
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (o *Organization) GetCreatedAt() time.Time {
+	if o == nil || o.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *o.CreatedAt
+}
+
+// GetDefaultRepoPermission returns the DefaultRepoPermission field if it's non-nil, zero value otherwise.
+func (o *Organization) GetDefaultRepoPermission() string {
+	if o == nil || o.DefaultRepoPermission == nil {
+		return ""
+	}
+	return *o.DefaultRepoPermission
+}
+
+// GetDefaultRepoSettings returns the DefaultRepoSettings field if it's non-nil, zero value otherwise.
+func (o *Organization) GetDefaultRepoSettings() string {
+	if o == nil || o.DefaultRepoSettings == nil {
+		return ""
+	}
+	return *o.DefaultRepoSettings
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (o *Organization) GetDescription() string {
+	if o == nil || o.Description == nil {
+		return ""
+	}
+	return *o.Description
+}
+
+// GetDiskUsage returns the DiskUsage field if it's non-nil, zero value otherwise.
+func (o *Organization) GetDiskUsage() int {
+	if o == nil || o.DiskUsage == nil {
+		return 0
+	}
+	return *o.DiskUsage
+}
+
+// GetEmail returns the Email field if it's non-nil, zero value otherwise.
+func (o *Organization) GetEmail() string {
+	if o == nil || o.Email == nil {
+		return ""
+	}
+	return *o.Email
+}
+
+// GetEventsURL returns the EventsURL field if it's non-nil, zero value otherwise.
+func (o *Organization) GetEventsURL() string {
+	if o == nil || o.EventsURL == nil {
+		return ""
+	}
+	return *o.EventsURL
+}
+
+// GetFollowers returns the Followers field if it's non-nil, zero value otherwise.
+func (o *Organization) GetFollowers() int {
+	if o == nil || o.Followers == nil {
+		return 0
+	}
+	return *o.Followers
+}
+
+// GetFollowing returns the Following field if it's non-nil, zero value otherwise.
+func (o *Organization) GetFollowing() int {
+	if o == nil || o.Following == nil {
+		return 0
+	}
+	return *o.Following
+}
+
+// GetHooksURL returns the HooksURL field if it's non-nil, zero value otherwise.
+func (o *Organization) GetHooksURL() string {
+	if o == nil || o.HooksURL == nil {
+		return ""
+	}
+	return *o.HooksURL
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (o *Organization) GetHTMLURL() string {
+	if o == nil || o.HTMLURL == nil {
+		return ""
+	}
+	return *o.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (o *Organization) GetID() int64 {
+	if o == nil || o.ID == nil {
+		return 0
+	}
+	return *o.ID
+}
+
+// GetIssuesURL returns the IssuesURL field if it's non-nil, zero value otherwise.
+func (o *Organization) GetIssuesURL() string {
+	if o == nil || o.IssuesURL == nil {
+		return ""
+	}
+	return *o.IssuesURL
+}
+
+// GetLocation returns the Location field if it's non-nil, zero value otherwise.
+func (o *Organization) GetLocation() string {
+	if o == nil || o.Location == nil {
+		return ""
+	}
+	return *o.Location
+}
+
+// GetLogin returns the Login field if it's non-nil, zero value otherwise.
+func (o *Organization) GetLogin() string {
+	if o == nil || o.Login == nil {
+		return ""
+	}
+	return *o.Login
+}
+
+// GetMembersCanCreateRepos returns the MembersCanCreateRepos field if it's non-nil, zero value otherwise.
+func (o *Organization) GetMembersCanCreateRepos() bool {
+	if o == nil || o.MembersCanCreateRepos == nil {
+		return false
+	}
+	return *o.MembersCanCreateRepos
+}
+
+// GetMembersURL returns the MembersURL field if it's non-nil, zero value otherwise.
+func (o *Organization) GetMembersURL() string {
+	if o == nil || o.MembersURL == nil {
+		return ""
+	}
+	return *o.MembersURL
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (o *Organization) GetName() string {
+	if o == nil || o.Name == nil {
+		return ""
+	}
+	return *o.Name
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (o *Organization) GetNodeID() string {
+	if o == nil || o.NodeID == nil {
+		return ""
+	}
+	return *o.NodeID
+}
+
+// GetOwnedPrivateRepos returns the OwnedPrivateRepos field if it's non-nil, zero value otherwise.
+func (o *Organization) GetOwnedPrivateRepos() int {
+	if o == nil || o.OwnedPrivateRepos == nil {
+		return 0
+	}
+	return *o.OwnedPrivateRepos
+}
+
+// GetPlan returns the Plan field.
+func (o *Organization) GetPlan() *Plan {
+	if o == nil {
+		return nil
+	}
+	return o.Plan
+}
+
+// GetPrivateGists returns the PrivateGists field if it's non-nil, zero value otherwise.
+func (o *Organization) GetPrivateGists() int {
+	if o == nil || o.PrivateGists == nil {
+		return 0
+	}
+	return *o.PrivateGists
+}
+
+// GetPublicGists returns the PublicGists field if it's non-nil, zero value otherwise.
+func (o *Organization) GetPublicGists() int {
+	if o == nil || o.PublicGists == nil {
+		return 0
+	}
+	return *o.PublicGists
+}
+
+// GetPublicMembersURL returns the PublicMembersURL field if it's non-nil, zero value otherwise.
+func (o *Organization) GetPublicMembersURL() string {
+	if o == nil || o.PublicMembersURL == nil {
+		return ""
+	}
+	return *o.PublicMembersURL
+}
+
+// GetPublicRepos returns the PublicRepos field if it's non-nil, zero value otherwise.
+func (o *Organization) GetPublicRepos() int {
+	if o == nil || o.PublicRepos == nil {
+		return 0
+	}
+	return *o.PublicRepos
+}
+
+// GetReposURL returns the ReposURL field if it's non-nil, zero value otherwise.
+func (o *Organization) GetReposURL() string {
+	if o == nil || o.ReposURL == nil {
+		return ""
+	}
+	return *o.ReposURL
+}
+
+// GetTotalPrivateRepos returns the TotalPrivateRepos field if it's non-nil, zero value otherwise.
+func (o *Organization) GetTotalPrivateRepos() int {
+	if o == nil || o.TotalPrivateRepos == nil {
+		return 0
+	}
+	return *o.TotalPrivateRepos
+}
+
+// GetTwoFactorRequirementEnabled returns the TwoFactorRequirementEnabled field if it's non-nil, zero value otherwise.
+func (o *Organization) GetTwoFactorRequirementEnabled() bool {
+	if o == nil || o.TwoFactorRequirementEnabled == nil {
+		return false
+	}
+	return *o.TwoFactorRequirementEnabled
+}
+
+// GetType returns the Type field if it's non-nil, zero value otherwise.
+func (o *Organization) GetType() string {
+	if o == nil || o.Type == nil {
+		return ""
+	}
+	return *o.Type
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (o *Organization) GetUpdatedAt() time.Time {
+	if o == nil || o.UpdatedAt == nil {
+		return time.Time{}
+	}
+	return *o.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (o *Organization) GetURL() string {
+	if o == nil || o.URL == nil {
+		return ""
+	}
+	return *o.URL
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (o *OrganizationEvent) GetAction() string {
+	if o == nil || o.Action == nil {
+		return ""
+	}
+	return *o.Action
+}
+
+// GetInstallation returns the Installation field.
+func (o *OrganizationEvent) GetInstallation() *Installation {
+	if o == nil {
+		return nil
+	}
+	return o.Installation
+}
+
+// GetInvitation returns the Invitation field.
+func (o *OrganizationEvent) GetInvitation() *Invitation {
+	if o == nil {
+		return nil
+	}
+	return o.Invitation
+}
+
+// GetMembership returns the Membership field.
+func (o *OrganizationEvent) GetMembership() *Membership {
+	if o == nil {
+		return nil
+	}
+	return o.Membership
+}
+
+// GetOrganization returns the Organization field.
+func (o *OrganizationEvent) GetOrganization() *Organization {
+	if o == nil {
+		return nil
+	}
+	return o.Organization
+}
+
+// GetSender returns the Sender field.
+func (o *OrganizationEvent) GetSender() *User {
+	if o == nil {
+		return nil
+	}
+	return o.Sender
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (o *OrgBlockEvent) GetAction() string {
+	if o == nil || o.Action == nil {
+		return ""
+	}
+	return *o.Action
+}
+
+// GetBlockedUser returns the BlockedUser field.
+func (o *OrgBlockEvent) GetBlockedUser() *User {
+	if o == nil {
+		return nil
+	}
+	return o.BlockedUser
+}
+
+// GetInstallation returns the Installation field.
+func (o *OrgBlockEvent) GetInstallation() *Installation {
+	if o == nil {
+		return nil
+	}
+	return o.Installation
+}
+
+// GetOrganization returns the Organization field.
+func (o *OrgBlockEvent) GetOrganization() *Organization {
+	if o == nil {
+		return nil
+	}
+	return o.Organization
+}
+
+// GetSender returns the Sender field.
+func (o *OrgBlockEvent) GetSender() *User {
+	if o == nil {
+		return nil
+	}
+	return o.Sender
+}
+
+// GetDisabledOrgs returns the DisabledOrgs field if it's non-nil, zero value otherwise.
+func (o *OrgStats) GetDisabledOrgs() int {
+	if o == nil || o.DisabledOrgs == nil {
+		return 0
+	}
+	return *o.DisabledOrgs
+}
+
+// GetTotalOrgs returns the TotalOrgs field if it's non-nil, zero value otherwise.
+func (o *OrgStats) GetTotalOrgs() int {
+	if o == nil || o.TotalOrgs == nil {
+		return 0
+	}
+	return *o.TotalOrgs
+}
+
+// GetTotalTeamMembers returns the TotalTeamMembers field if it's non-nil, zero value otherwise.
+func (o *OrgStats) GetTotalTeamMembers() int {
+	if o == nil || o.TotalTeamMembers == nil {
+		return 0
+	}
+	return *o.TotalTeamMembers
+}
+
+// GetTotalTeams returns the TotalTeams field if it's non-nil, zero value otherwise.
+func (o *OrgStats) GetTotalTeams() int {
+	if o == nil || o.TotalTeams == nil {
+		return 0
+	}
+	return *o.TotalTeams
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (p *Page) GetAction() string {
+	if p == nil || p.Action == nil {
+		return ""
+	}
+	return *p.Action
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (p *Page) GetHTMLURL() string {
+	if p == nil || p.HTMLURL == nil {
+		return ""
+	}
+	return *p.HTMLURL
+}
+
+// GetPageName returns the PageName field if it's non-nil, zero value otherwise.
+func (p *Page) GetPageName() string {
+	if p == nil || p.PageName == nil {
+		return ""
+	}
+	return *p.PageName
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (p *Page) GetSHA() string {
+	if p == nil || p.SHA == nil {
+		return ""
+	}
+	return *p.SHA
+}
+
+// GetSummary returns the Summary field if it's non-nil, zero value otherwise.
+func (p *Page) GetSummary() string {
+	if p == nil || p.Summary == nil {
+		return ""
+	}
+	return *p.Summary
+}
+
+// GetTitle returns the Title field if it's non-nil, zero value otherwise.
+func (p *Page) GetTitle() string {
+	if p == nil || p.Title == nil {
+		return ""
+	}
+	return *p.Title
+}
+
+// GetBuild returns the Build field.
+func (p *PageBuildEvent) GetBuild() *PagesBuild {
+	if p == nil {
+		return nil
+	}
+	return p.Build
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (p *PageBuildEvent) GetID() int64 {
+	if p == nil || p.ID == nil {
+		return 0
+	}
+	return *p.ID
+}
+
+// GetInstallation returns the Installation field.
+func (p *PageBuildEvent) GetInstallation() *Installation {
+	if p == nil {
+		return nil
+	}
+	return p.Installation
+}
+
+// GetRepo returns the Repo field.
+func (p *PageBuildEvent) GetRepo() *Repository {
+	if p == nil {
+		return nil
+	}
+	return p.Repo
+}
+
+// GetSender returns the Sender field.
+func (p *PageBuildEvent) GetSender() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Sender
+}
+
+// GetCNAME returns the CNAME field if it's non-nil, zero value otherwise.
+func (p *Pages) GetCNAME() string {
+	if p == nil || p.CNAME == nil {
+		return ""
+	}
+	return *p.CNAME
+}
+
+// GetCustom404 returns the Custom404 field if it's non-nil, zero value otherwise.
+func (p *Pages) GetCustom404() bool {
+	if p == nil || p.Custom404 == nil {
+		return false
+	}
+	return *p.Custom404
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (p *Pages) GetHTMLURL() string {
+	if p == nil || p.HTMLURL == nil {
+		return ""
+	}
+	return *p.HTMLURL
+}
+
+// GetStatus returns the Status field if it's non-nil, zero value otherwise.
+func (p *Pages) GetStatus() string {
+	if p == nil || p.Status == nil {
+		return ""
+	}
+	return *p.Status
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (p *Pages) GetURL() string {
+	if p == nil || p.URL == nil {
+		return ""
+	}
+	return *p.URL
+}
+
+// GetCommit returns the Commit field if it's non-nil, zero value otherwise.
+func (p *PagesBuild) GetCommit() string {
+	if p == nil || p.Commit == nil {
+		return ""
+	}
+	return *p.Commit
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (p *PagesBuild) GetCreatedAt() Timestamp {
+	if p == nil || p.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *p.CreatedAt
+}
+
+// GetDuration returns the Duration field if it's non-nil, zero value otherwise.
+func (p *PagesBuild) GetDuration() int {
+	if p == nil || p.Duration == nil {
+		return 0
+	}
+	return *p.Duration
+}
+
+// GetError returns the Error field.
+func (p *PagesBuild) GetError() *PagesError {
+	if p == nil {
+		return nil
+	}
+	return p.Error
+}
+
+// GetPusher returns the Pusher field.
+func (p *PagesBuild) GetPusher() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Pusher
+}
+
+// GetStatus returns the Status field if it's non-nil, zero value otherwise.
+func (p *PagesBuild) GetStatus() string {
+	if p == nil || p.Status == nil {
+		return ""
+	}
+	return *p.Status
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (p *PagesBuild) GetUpdatedAt() Timestamp {
+	if p == nil || p.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *p.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (p *PagesBuild) GetURL() string {
+	if p == nil || p.URL == nil {
+		return ""
+	}
+	return *p.URL
+}
+
+// GetMessage returns the Message field if it's non-nil, zero value otherwise.
+func (p *PagesError) GetMessage() string {
+	if p == nil || p.Message == nil {
+		return ""
+	}
+	return *p.Message
+}
+
+// GetTotalPages returns the TotalPages field if it's non-nil, zero value otherwise.
+func (p *PageStats) GetTotalPages() int {
+	if p == nil || p.TotalPages == nil {
+		return 0
+	}
+	return *p.TotalPages
+}
+
+// GetHook returns the Hook field.
+func (p *PingEvent) GetHook() *Hook {
+	if p == nil {
+		return nil
+	}
+	return p.Hook
+}
+
+// GetHookID returns the HookID field if it's non-nil, zero value otherwise.
+func (p *PingEvent) GetHookID() int64 {
+	if p == nil || p.HookID == nil {
+		return 0
+	}
+	return *p.HookID
+}
+
+// GetInstallation returns the Installation field.
+func (p *PingEvent) GetInstallation() *Installation {
+	if p == nil {
+		return nil
+	}
+	return p.Installation
+}
+
+// GetZen returns the Zen field if it's non-nil, zero value otherwise.
+func (p *PingEvent) GetZen() string {
+	if p == nil || p.Zen == nil {
+		return ""
+	}
+	return *p.Zen
+}
+
+// GetCollaborators returns the Collaborators field if it's non-nil, zero value otherwise.
+func (p *Plan) GetCollaborators() int {
+	if p == nil || p.Collaborators == nil {
+		return 0
+	}
+	return *p.Collaborators
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (p *Plan) GetName() string {
+	if p == nil || p.Name == nil {
+		return ""
+	}
+	return *p.Name
+}
+
+// GetPrivateRepos returns the PrivateRepos field if it's non-nil, zero value otherwise.
+func (p *Plan) GetPrivateRepos() int {
+	if p == nil || p.PrivateRepos == nil {
+		return 0
+	}
+	return *p.PrivateRepos
+}
+
+// GetSpace returns the Space field if it's non-nil, zero value otherwise.
+func (p *Plan) GetSpace() int {
+	if p == nil || p.Space == nil {
+		return 0
+	}
+	return *p.Space
+}
+
+// GetConfigURL returns the ConfigURL field if it's non-nil, zero value otherwise.
+func (p *PreReceiveHook) GetConfigURL() string {
+	if p == nil || p.ConfigURL == nil {
+		return ""
+	}
+	return *p.ConfigURL
+}
+
+// GetEnforcement returns the Enforcement field if it's non-nil, zero value otherwise.
+func (p *PreReceiveHook) GetEnforcement() string {
+	if p == nil || p.Enforcement == nil {
+		return ""
+	}
+	return *p.Enforcement
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (p *PreReceiveHook) GetID() int64 {
+	if p == nil || p.ID == nil {
+		return 0
+	}
+	return *p.ID
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (p *PreReceiveHook) GetName() string {
+	if p == nil || p.Name == nil {
+		return ""
+	}
+	return *p.Name
+}
+
+// GetHRef returns the HRef field if it's non-nil, zero value otherwise.
+func (p *PRLink) GetHRef() string {
+	if p == nil || p.HRef == nil {
+		return ""
+	}
+	return *p.HRef
+}
+
+// GetComments returns the Comments field.
+func (p *PRLinks) GetComments() *PRLink {
+	if p == nil {
+		return nil
+	}
+	return p.Comments
+}
+
+// GetCommits returns the Commits field.
+func (p *PRLinks) GetCommits() *PRLink {
+	if p == nil {
+		return nil
+	}
+	return p.Commits
+}
+
+// GetHTML returns the HTML field.
+func (p *PRLinks) GetHTML() *PRLink {
+	if p == nil {
+		return nil
+	}
+	return p.HTML
+}
+
+// GetIssue returns the Issue field.
+func (p *PRLinks) GetIssue() *PRLink {
+	if p == nil {
+		return nil
+	}
+	return p.Issue
+}
+
+// GetReviewComment returns the ReviewComment field.
+func (p *PRLinks) GetReviewComment() *PRLink {
+	if p == nil {
+		return nil
+	}
+	return p.ReviewComment
+}
+
+// GetReviewComments returns the ReviewComments field.
+func (p *PRLinks) GetReviewComments() *PRLink {
+	if p == nil {
+		return nil
+	}
+	return p.ReviewComments
+}
+
+// GetSelf returns the Self field.
+func (p *PRLinks) GetSelf() *PRLink {
+	if p == nil {
+		return nil
+	}
+	return p.Self
+}
+
+// GetStatuses returns the Statuses field.
+func (p *PRLinks) GetStatuses() *PRLink {
+	if p == nil {
+		return nil
+	}
+	return p.Statuses
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (p *Project) GetBody() string {
+	if p == nil || p.Body == nil {
+		return ""
+	}
+	return *p.Body
+}
+
+// GetColumnsURL returns the ColumnsURL field if it's non-nil, zero value otherwise.
+func (p *Project) GetColumnsURL() string {
+	if p == nil || p.ColumnsURL == nil {
+		return ""
+	}
+	return *p.ColumnsURL
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (p *Project) GetCreatedAt() Timestamp {
+	if p == nil || p.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *p.CreatedAt
+}
+
+// GetCreator returns the Creator field.
+func (p *Project) GetCreator() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Creator
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (p *Project) GetHTMLURL() string {
+	if p == nil || p.HTMLURL == nil {
+		return ""
+	}
+	return *p.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (p *Project) GetID() int64 {
+	if p == nil || p.ID == nil {
+		return 0
+	}
+	return *p.ID
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (p *Project) GetName() string {
+	if p == nil || p.Name == nil {
+		return ""
+	}
+	return *p.Name
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (p *Project) GetNodeID() string {
+	if p == nil || p.NodeID == nil {
+		return ""
+	}
+	return *p.NodeID
+}
+
+// GetNumber returns the Number field if it's non-nil, zero value otherwise.
+func (p *Project) GetNumber() int {
+	if p == nil || p.Number == nil {
+		return 0
+	}
+	return *p.Number
+}
+
+// GetOwnerURL returns the OwnerURL field if it's non-nil, zero value otherwise.
+func (p *Project) GetOwnerURL() string {
+	if p == nil || p.OwnerURL == nil {
+		return ""
+	}
+	return *p.OwnerURL
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (p *Project) GetState() string {
+	if p == nil || p.State == nil {
+		return ""
+	}
+	return *p.State
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (p *Project) GetUpdatedAt() Timestamp {
+	if p == nil || p.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *p.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (p *Project) GetURL() string {
+	if p == nil || p.URL == nil {
+		return ""
+	}
+	return *p.URL
+}
+
+// GetArchived returns the Archived field if it's non-nil, zero value otherwise.
+func (p *ProjectCard) GetArchived() bool {
+	if p == nil || p.Archived == nil {
+		return false
+	}
+	return *p.Archived
+}
+
+// GetColumnID returns the ColumnID field if it's non-nil, zero value otherwise.
+func (p *ProjectCard) GetColumnID() int64 {
+	if p == nil || p.ColumnID == nil {
+		return 0
+	}
+	return *p.ColumnID
+}
+
+// GetColumnName returns the ColumnName field if it's non-nil, zero value otherwise.
+func (p *ProjectCard) GetColumnName() string {
+	if p == nil || p.ColumnName == nil {
+		return ""
+	}
+	return *p.ColumnName
+}
+
+// GetColumnURL returns the ColumnURL field if it's non-nil, zero value otherwise.
+func (p *ProjectCard) GetColumnURL() string {
+	if p == nil || p.ColumnURL == nil {
+		return ""
+	}
+	return *p.ColumnURL
+}
+
+// GetContentURL returns the ContentURL field if it's non-nil, zero value otherwise.
+func (p *ProjectCard) GetContentURL() string {
+	if p == nil || p.ContentURL == nil {
+		return ""
+	}
+	return *p.ContentURL
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (p *ProjectCard) GetCreatedAt() Timestamp {
+	if p == nil || p.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *p.CreatedAt
+}
+
+// GetCreator returns the Creator field.
+func (p *ProjectCard) GetCreator() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Creator
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (p *ProjectCard) GetID() int64 {
+	if p == nil || p.ID == nil {
+		return 0
+	}
+	return *p.ID
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (p *ProjectCard) GetNodeID() string {
+	if p == nil || p.NodeID == nil {
+		return ""
+	}
+	return *p.NodeID
+}
+
+// GetNote returns the Note field if it's non-nil, zero value otherwise.
+func (p *ProjectCard) GetNote() string {
+	if p == nil || p.Note == nil {
+		return ""
+	}
+	return *p.Note
+}
+
+// GetPreviousColumnName returns the PreviousColumnName field if it's non-nil, zero value otherwise.
+func (p *ProjectCard) GetPreviousColumnName() string {
+	if p == nil || p.PreviousColumnName == nil {
+		return ""
+	}
+	return *p.PreviousColumnName
+}
+
+// GetProjectID returns the ProjectID field if it's non-nil, zero value otherwise.
+func (p *ProjectCard) GetProjectID() int64 {
+	if p == nil || p.ProjectID == nil {
+		return 0
+	}
+	return *p.ProjectID
+}
+
+// GetProjectURL returns the ProjectURL field if it's non-nil, zero value otherwise.
+func (p *ProjectCard) GetProjectURL() string {
+	if p == nil || p.ProjectURL == nil {
+		return ""
+	}
+	return *p.ProjectURL
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (p *ProjectCard) GetUpdatedAt() Timestamp {
+	if p == nil || p.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *p.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (p *ProjectCard) GetURL() string {
+	if p == nil || p.URL == nil {
+		return ""
+	}
+	return *p.URL
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (p *ProjectCardEvent) GetAction() string {
+	if p == nil || p.Action == nil {
+		return ""
+	}
+	return *p.Action
+}
+
+// GetAfterID returns the AfterID field if it's non-nil, zero value otherwise.
+func (p *ProjectCardEvent) GetAfterID() int64 {
+	if p == nil || p.AfterID == nil {
+		return 0
+	}
+	return *p.AfterID
+}
+
+// GetChanges returns the Changes field.
+func (p *ProjectCardEvent) GetChanges() *ProjectCardChange {
+	if p == nil {
+		return nil
+	}
+	return p.Changes
+}
+
+// GetInstallation returns the Installation field.
+func (p *ProjectCardEvent) GetInstallation() *Installation {
+	if p == nil {
+		return nil
+	}
+	return p.Installation
+}
+
+// GetOrg returns the Org field.
+func (p *ProjectCardEvent) GetOrg() *Organization {
+	if p == nil {
+		return nil
+	}
+	return p.Org
+}
+
+// GetProjectCard returns the ProjectCard field.
+func (p *ProjectCardEvent) GetProjectCard() *ProjectCard {
+	if p == nil {
+		return nil
+	}
+	return p.ProjectCard
+}
+
+// GetRepo returns the Repo field.
+func (p *ProjectCardEvent) GetRepo() *Repository {
+	if p == nil {
+		return nil
+	}
+	return p.Repo
+}
+
+// GetSender returns the Sender field.
+func (p *ProjectCardEvent) GetSender() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Sender
+}
+
+// GetArchivedState returns the ArchivedState field if it's non-nil, zero value otherwise.
+func (p *ProjectCardListOptions) GetArchivedState() string {
+	if p == nil || p.ArchivedState == nil {
+		return ""
+	}
+	return *p.ArchivedState
+}
+
+// GetArchived returns the Archived field if it's non-nil, zero value otherwise.
+func (p *ProjectCardOptions) GetArchived() bool {
+	if p == nil || p.Archived == nil {
+		return false
+	}
+	return *p.Archived
+}
+
+// GetPermission returns the Permission field if it's non-nil, zero value otherwise.
+func (p *ProjectCollaboratorOptions) GetPermission() string {
+	if p == nil || p.Permission == nil {
+		return ""
+	}
+	return *p.Permission
+}
+
+// GetCardsURL returns the CardsURL field if it's non-nil, zero value otherwise.
+func (p *ProjectColumn) GetCardsURL() string {
+	if p == nil || p.CardsURL == nil {
+		return ""
+	}
+	return *p.CardsURL
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (p *ProjectColumn) GetCreatedAt() Timestamp {
+	if p == nil || p.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *p.CreatedAt
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (p *ProjectColumn) GetID() int64 {
+	if p == nil || p.ID == nil {
+		return 0
+	}
+	return *p.ID
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (p *ProjectColumn) GetName() string {
+	if p == nil || p.Name == nil {
+		return ""
+	}
+	return *p.Name
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (p *ProjectColumn) GetNodeID() string {
+	if p == nil || p.NodeID == nil {
+		return ""
+	}
+	return *p.NodeID
+}
+
+// GetProjectURL returns the ProjectURL field if it's non-nil, zero value otherwise.
+func (p *ProjectColumn) GetProjectURL() string {
+	if p == nil || p.ProjectURL == nil {
+		return ""
+	}
+	return *p.ProjectURL
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (p *ProjectColumn) GetUpdatedAt() Timestamp {
+	if p == nil || p.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *p.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (p *ProjectColumn) GetURL() string {
+	if p == nil || p.URL == nil {
+		return ""
+	}
+	return *p.URL
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (p *ProjectColumnEvent) GetAction() string {
+	if p == nil || p.Action == nil {
+		return ""
+	}
+	return *p.Action
+}
+
+// GetAfterID returns the AfterID field if it's non-nil, zero value otherwise.
+func (p *ProjectColumnEvent) GetAfterID() int64 {
+	if p == nil || p.AfterID == nil {
+		return 0
+	}
+	return *p.AfterID
+}
+
+// GetChanges returns the Changes field.
+func (p *ProjectColumnEvent) GetChanges() *ProjectColumnChange {
+	if p == nil {
+		return nil
+	}
+	return p.Changes
+}
+
+// GetInstallation returns the Installation field.
+func (p *ProjectColumnEvent) GetInstallation() *Installation {
+	if p == nil {
+		return nil
+	}
+	return p.Installation
+}
+
+// GetOrg returns the Org field.
+func (p *ProjectColumnEvent) GetOrg() *Organization {
+	if p == nil {
+		return nil
+	}
+	return p.Org
+}
+
+// GetProjectColumn returns the ProjectColumn field.
+func (p *ProjectColumnEvent) GetProjectColumn() *ProjectColumn {
+	if p == nil {
+		return nil
+	}
+	return p.ProjectColumn
+}
+
+// GetRepo returns the Repo field.
+func (p *ProjectColumnEvent) GetRepo() *Repository {
+	if p == nil {
+		return nil
+	}
+	return p.Repo
+}
+
+// GetSender returns the Sender field.
+func (p *ProjectColumnEvent) GetSender() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Sender
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (p *ProjectEvent) GetAction() string {
+	if p == nil || p.Action == nil {
+		return ""
+	}
+	return *p.Action
+}
+
+// GetChanges returns the Changes field.
+func (p *ProjectEvent) GetChanges() *ProjectChange {
+	if p == nil {
+		return nil
+	}
+	return p.Changes
+}
+
+// GetInstallation returns the Installation field.
+func (p *ProjectEvent) GetInstallation() *Installation {
+	if p == nil {
+		return nil
+	}
+	return p.Installation
+}
+
+// GetOrg returns the Org field.
+func (p *ProjectEvent) GetOrg() *Organization {
+	if p == nil {
+		return nil
+	}
+	return p.Org
+}
+
+// GetProject returns the Project field.
+func (p *ProjectEvent) GetProject() *Project {
+	if p == nil {
+		return nil
+	}
+	return p.Project
+}
+
+// GetRepo returns the Repo field.
+func (p *ProjectEvent) GetRepo() *Repository {
+	if p == nil {
+		return nil
+	}
+	return p.Repo
+}
+
+// GetSender returns the Sender field.
+func (p *ProjectEvent) GetSender() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Sender
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (p *ProjectOptions) GetBody() string {
+	if p == nil || p.Body == nil {
+		return ""
+	}
+	return *p.Body
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (p *ProjectOptions) GetName() string {
+	if p == nil || p.Name == nil {
+		return ""
+	}
+	return *p.Name
+}
+
+// GetOrganizationPermission returns the OrganizationPermission field if it's non-nil, zero value otherwise.
+func (p *ProjectOptions) GetOrganizationPermission() string {
+	if p == nil || p.OrganizationPermission == nil {
+		return ""
+	}
+	return *p.OrganizationPermission
+}
+
+// GetPublic returns the Public field if it's non-nil, zero value otherwise.
+func (p *ProjectOptions) GetPublic() bool {
+	if p == nil || p.Public == nil {
+		return false
+	}
+	return *p.Public
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (p *ProjectOptions) GetState() string {
+	if p == nil || p.State == nil {
+		return ""
+	}
+	return *p.State
+}
+
+// GetPermission returns the Permission field if it's non-nil, zero value otherwise.
+func (p *ProjectPermissionLevel) GetPermission() string {
+	if p == nil || p.Permission == nil {
+		return ""
+	}
+	return *p.Permission
+}
+
+// GetUser returns the User field.
+func (p *ProjectPermissionLevel) GetUser() *User {
+	if p == nil {
+		return nil
+	}
+	return p.User
+}
+
+// GetEnforceAdmins returns the EnforceAdmins field.
+func (p *Protection) GetEnforceAdmins() *AdminEnforcement {
+	if p == nil {
+		return nil
+	}
+	return p.EnforceAdmins
+}
+
+// GetRequiredPullRequestReviews returns the RequiredPullRequestReviews field.
+func (p *Protection) GetRequiredPullRequestReviews() *PullRequestReviewsEnforcement {
+	if p == nil {
+		return nil
+	}
+	return p.RequiredPullRequestReviews
+}
+
+// GetRequiredStatusChecks returns the RequiredStatusChecks field.
+func (p *Protection) GetRequiredStatusChecks() *RequiredStatusChecks {
+	if p == nil {
+		return nil
+	}
+	return p.RequiredStatusChecks
+}
+
+// GetRestrictions returns the Restrictions field.
+func (p *Protection) GetRestrictions() *BranchRestrictions {
+	if p == nil {
+		return nil
+	}
+	return p.Restrictions
+}
+
+// GetRequiredPullRequestReviews returns the RequiredPullRequestReviews field.
+func (p *ProtectionRequest) GetRequiredPullRequestReviews() *PullRequestReviewsEnforcementRequest {
+	if p == nil {
+		return nil
+	}
+	return p.RequiredPullRequestReviews
+}
+
+// GetRequiredStatusChecks returns the RequiredStatusChecks field.
+func (p *ProtectionRequest) GetRequiredStatusChecks() *RequiredStatusChecks {
+	if p == nil {
+		return nil
+	}
+	return p.RequiredStatusChecks
+}
+
+// GetRestrictions returns the Restrictions field.
+func (p *ProtectionRequest) GetRestrictions() *BranchRestrictionsRequest {
+	if p == nil {
+		return nil
+	}
+	return p.Restrictions
+}
+
+// GetInstallation returns the Installation field.
+func (p *PublicEvent) GetInstallation() *Installation {
+	if p == nil {
+		return nil
+	}
+	return p.Installation
+}
+
+// GetRepo returns the Repo field.
+func (p *PublicEvent) GetRepo() *Repository {
+	if p == nil {
+		return nil
+	}
+	return p.Repo
+}
+
+// GetSender returns the Sender field.
+func (p *PublicEvent) GetSender() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Sender
+}
+
+// GetActiveLockReason returns the ActiveLockReason field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetActiveLockReason() string {
+	if p == nil || p.ActiveLockReason == nil {
+		return ""
+	}
+	return *p.ActiveLockReason
+}
+
+// GetAdditions returns the Additions field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetAdditions() int {
+	if p == nil || p.Additions == nil {
+		return 0
+	}
+	return *p.Additions
+}
+
+// GetAssignee returns the Assignee field.
+func (p *PullRequest) GetAssignee() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Assignee
+}
+
+// GetAuthorAssociation returns the AuthorAssociation field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetAuthorAssociation() string {
+	if p == nil || p.AuthorAssociation == nil {
+		return ""
+	}
+	return *p.AuthorAssociation
+}
+
+// GetBase returns the Base field.
+func (p *PullRequest) GetBase() *PullRequestBranch {
+	if p == nil {
+		return nil
+	}
+	return p.Base
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetBody() string {
+	if p == nil || p.Body == nil {
+		return ""
+	}
+	return *p.Body
+}
+
+// GetChangedFiles returns the ChangedFiles field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetChangedFiles() int {
+	if p == nil || p.ChangedFiles == nil {
+		return 0
+	}
+	return *p.ChangedFiles
+}
+
+// GetClosedAt returns the ClosedAt field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetClosedAt() time.Time {
+	if p == nil || p.ClosedAt == nil {
+		return time.Time{}
+	}
+	return *p.ClosedAt
+}
+
+// GetComments returns the Comments field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetComments() int {
+	if p == nil || p.Comments == nil {
+		return 0
+	}
+	return *p.Comments
+}
+
+// GetCommentsURL returns the CommentsURL field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetCommentsURL() string {
+	if p == nil || p.CommentsURL == nil {
+		return ""
+	}
+	return *p.CommentsURL
+}
+
+// GetCommits returns the Commits field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetCommits() int {
+	if p == nil || p.Commits == nil {
+		return 0
+	}
+	return *p.Commits
+}
+
+// GetCommitsURL returns the CommitsURL field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetCommitsURL() string {
+	if p == nil || p.CommitsURL == nil {
+		return ""
+	}
+	return *p.CommitsURL
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetCreatedAt() time.Time {
+	if p == nil || p.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *p.CreatedAt
+}
+
+// GetDeletions returns the Deletions field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetDeletions() int {
+	if p == nil || p.Deletions == nil {
+		return 0
+	}
+	return *p.Deletions
+}
+
+// GetDiffURL returns the DiffURL field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetDiffURL() string {
+	if p == nil || p.DiffURL == nil {
+		return ""
+	}
+	return *p.DiffURL
+}
+
+// GetDraft returns the Draft field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetDraft() bool {
+	if p == nil || p.Draft == nil {
+		return false
+	}
+	return *p.Draft
+}
+
+// GetHead returns the Head field.
+func (p *PullRequest) GetHead() *PullRequestBranch {
+	if p == nil {
+		return nil
+	}
+	return p.Head
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetHTMLURL() string {
+	if p == nil || p.HTMLURL == nil {
+		return ""
+	}
+	return *p.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetID() int64 {
+	if p == nil || p.ID == nil {
+		return 0
+	}
+	return *p.ID
+}
+
+// GetIssueURL returns the IssueURL field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetIssueURL() string {
+	if p == nil || p.IssueURL == nil {
+		return ""
+	}
+	return *p.IssueURL
+}
+
+// GetLinks returns the Links field.
+func (p *PullRequest) GetLinks() *PRLinks {
+	if p == nil {
+		return nil
+	}
+	return p.Links
+}
+
+// GetMaintainerCanModify returns the MaintainerCanModify field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetMaintainerCanModify() bool {
+	if p == nil || p.MaintainerCanModify == nil {
+		return false
+	}
+	return *p.MaintainerCanModify
+}
+
+// GetMergeable returns the Mergeable field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetMergeable() bool {
+	if p == nil || p.Mergeable == nil {
+		return false
+	}
+	return *p.Mergeable
+}
+
+// GetMergeableState returns the MergeableState field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetMergeableState() string {
+	if p == nil || p.MergeableState == nil {
+		return ""
+	}
+	return *p.MergeableState
+}
+
+// GetMergeCommitSHA returns the MergeCommitSHA field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetMergeCommitSHA() string {
+	if p == nil || p.MergeCommitSHA == nil {
+		return ""
+	}
+	return *p.MergeCommitSHA
+}
+
+// GetMerged returns the Merged field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetMerged() bool {
+	if p == nil || p.Merged == nil {
+		return false
+	}
+	return *p.Merged
+}
+
+// GetMergedAt returns the MergedAt field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetMergedAt() time.Time {
+	if p == nil || p.MergedAt == nil {
+		return time.Time{}
+	}
+	return *p.MergedAt
+}
+
+// GetMergedBy returns the MergedBy field.
+func (p *PullRequest) GetMergedBy() *User {
+	if p == nil {
+		return nil
+	}
+	return p.MergedBy
+}
+
+// GetMilestone returns the Milestone field.
+func (p *PullRequest) GetMilestone() *Milestone {
+	if p == nil {
+		return nil
+	}
+	return p.Milestone
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetNodeID() string {
+	if p == nil || p.NodeID == nil {
+		return ""
+	}
+	return *p.NodeID
+}
+
+// GetNumber returns the Number field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetNumber() int {
+	if p == nil || p.Number == nil {
+		return 0
+	}
+	return *p.Number
+}
+
+// GetPatchURL returns the PatchURL field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetPatchURL() string {
+	if p == nil || p.PatchURL == nil {
+		return ""
+	}
+	return *p.PatchURL
+}
+
+// GetReviewComments returns the ReviewComments field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetReviewComments() int {
+	if p == nil || p.ReviewComments == nil {
+		return 0
+	}
+	return *p.ReviewComments
+}
+
+// GetReviewCommentsURL returns the ReviewCommentsURL field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetReviewCommentsURL() string {
+	if p == nil || p.ReviewCommentsURL == nil {
+		return ""
+	}
+	return *p.ReviewCommentsURL
+}
+
+// GetReviewCommentURL returns the ReviewCommentURL field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetReviewCommentURL() string {
+	if p == nil || p.ReviewCommentURL == nil {
+		return ""
+	}
+	return *p.ReviewCommentURL
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetState() string {
+	if p == nil || p.State == nil {
+		return ""
+	}
+	return *p.State
+}
+
+// GetStatusesURL returns the StatusesURL field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetStatusesURL() string {
+	if p == nil || p.StatusesURL == nil {
+		return ""
+	}
+	return *p.StatusesURL
+}
+
+// GetTitle returns the Title field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetTitle() string {
+	if p == nil || p.Title == nil {
+		return ""
+	}
+	return *p.Title
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetUpdatedAt() time.Time {
+	if p == nil || p.UpdatedAt == nil {
+		return time.Time{}
+	}
+	return *p.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetURL() string {
+	if p == nil || p.URL == nil {
+		return ""
+	}
+	return *p.URL
+}
+
+// GetUser returns the User field.
+func (p *PullRequest) GetUser() *User {
+	if p == nil {
+		return nil
+	}
+	return p.User
+}
+
+// GetLabel returns the Label field if it's non-nil, zero value otherwise.
+func (p *PullRequestBranch) GetLabel() string {
+	if p == nil || p.Label == nil {
+		return ""
+	}
+	return *p.Label
+}
+
+// GetRef returns the Ref field if it's non-nil, zero value otherwise.
+func (p *PullRequestBranch) GetRef() string {
+	if p == nil || p.Ref == nil {
+		return ""
+	}
+	return *p.Ref
+}
+
+// GetRepo returns the Repo field.
+func (p *PullRequestBranch) GetRepo() *Repository {
+	if p == nil {
+		return nil
+	}
+	return p.Repo
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (p *PullRequestBranch) GetSHA() string {
+	if p == nil || p.SHA == nil {
+		return ""
+	}
+	return *p.SHA
+}
+
+// GetUser returns the User field.
+func (p *PullRequestBranch) GetUser() *User {
+	if p == nil {
+		return nil
+	}
+	return p.User
+}
+
+// GetAuthorAssociation returns the AuthorAssociation field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetAuthorAssociation() string {
+	if p == nil || p.AuthorAssociation == nil {
+		return ""
+	}
+	return *p.AuthorAssociation
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetBody() string {
+	if p == nil || p.Body == nil {
+		return ""
+	}
+	return *p.Body
+}
+
+// GetCommitID returns the CommitID field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetCommitID() string {
+	if p == nil || p.CommitID == nil {
+		return ""
+	}
+	return *p.CommitID
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetCreatedAt() time.Time {
+	if p == nil || p.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *p.CreatedAt
+}
+
+// GetDiffHunk returns the DiffHunk field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetDiffHunk() string {
+	if p == nil || p.DiffHunk == nil {
+		return ""
+	}
+	return *p.DiffHunk
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetHTMLURL() string {
+	if p == nil || p.HTMLURL == nil {
+		return ""
+	}
+	return *p.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetID() int64 {
+	if p == nil || p.ID == nil {
+		return 0
+	}
+	return *p.ID
+}
+
+// GetInReplyTo returns the InReplyTo field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetInReplyTo() int64 {
+	if p == nil || p.InReplyTo == nil {
+		return 0
+	}
+	return *p.InReplyTo
+}
+
+// GetOriginalCommitID returns the OriginalCommitID field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetOriginalCommitID() string {
+	if p == nil || p.OriginalCommitID == nil {
+		return ""
+	}
+	return *p.OriginalCommitID
+}
+
+// GetOriginalPosition returns the OriginalPosition field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetOriginalPosition() int {
+	if p == nil || p.OriginalPosition == nil {
+		return 0
+	}
+	return *p.OriginalPosition
+}
+
+// GetPath returns the Path field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetPath() string {
+	if p == nil || p.Path == nil {
+		return ""
+	}
+	return *p.Path
+}
+
+// GetPosition returns the Position field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetPosition() int {
+	if p == nil || p.Position == nil {
+		return 0
+	}
+	return *p.Position
+}
+
+// GetPullRequestReviewID returns the PullRequestReviewID field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetPullRequestReviewID() int64 {
+	if p == nil || p.PullRequestReviewID == nil {
+		return 0
+	}
+	return *p.PullRequestReviewID
+}
+
+// GetPullRequestURL returns the PullRequestURL field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetPullRequestURL() string {
+	if p == nil || p.PullRequestURL == nil {
+		return ""
+	}
+	return *p.PullRequestURL
+}
+
+// GetReactions returns the Reactions field.
+func (p *PullRequestComment) GetReactions() *Reactions {
+	if p == nil {
+		return nil
+	}
+	return p.Reactions
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetUpdatedAt() time.Time {
+	if p == nil || p.UpdatedAt == nil {
+		return time.Time{}
+	}
+	return *p.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetURL() string {
+	if p == nil || p.URL == nil {
+		return ""
+	}
+	return *p.URL
+}
+
+// GetUser returns the User field.
+func (p *PullRequestComment) GetUser() *User {
+	if p == nil {
+		return nil
+	}
+	return p.User
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (p *PullRequestEvent) GetAction() string {
+	if p == nil || p.Action == nil {
+		return ""
+	}
+	return *p.Action
+}
+
+// GetAssignee returns the Assignee field.
+func (p *PullRequestEvent) GetAssignee() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Assignee
+}
+
+// GetChanges returns the Changes field.
+func (p *PullRequestEvent) GetChanges() *EditChange {
+	if p == nil {
+		return nil
+	}
+	return p.Changes
+}
+
+// GetInstallation returns the Installation field.
+func (p *PullRequestEvent) GetInstallation() *Installation {
+	if p == nil {
+		return nil
+	}
+	return p.Installation
+}
+
+// GetLabel returns the Label field.
+func (p *PullRequestEvent) GetLabel() *Label {
+	if p == nil {
+		return nil
+	}
+	return p.Label
+}
+
+// GetNumber returns the Number field if it's non-nil, zero value otherwise.
+func (p *PullRequestEvent) GetNumber() int {
+	if p == nil || p.Number == nil {
+		return 0
+	}
+	return *p.Number
+}
+
+// GetOrganization returns the Organization field.
+func (p *PullRequestEvent) GetOrganization() *Organization {
+	if p == nil {
+		return nil
+	}
+	return p.Organization
+}
+
+// GetPullRequest returns the PullRequest field.
+func (p *PullRequestEvent) GetPullRequest() *PullRequest {
+	if p == nil {
+		return nil
+	}
+	return p.PullRequest
+}
+
+// GetRepo returns the Repo field.
+func (p *PullRequestEvent) GetRepo() *Repository {
+	if p == nil {
+		return nil
+	}
+	return p.Repo
+}
+
+// GetRequestedReviewer returns the RequestedReviewer field.
+func (p *PullRequestEvent) GetRequestedReviewer() *User {
+	if p == nil {
+		return nil
+	}
+	return p.RequestedReviewer
+}
+
+// GetSender returns the Sender field.
+func (p *PullRequestEvent) GetSender() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Sender
+}
+
+// GetDiffURL returns the DiffURL field if it's non-nil, zero value otherwise.
+func (p *PullRequestLinks) GetDiffURL() string {
+	if p == nil || p.DiffURL == nil {
+		return ""
+	}
+	return *p.DiffURL
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (p *PullRequestLinks) GetHTMLURL() string {
+	if p == nil || p.HTMLURL == nil {
+		return ""
+	}
+	return *p.HTMLURL
+}
+
+// GetPatchURL returns the PatchURL field if it's non-nil, zero value otherwise.
+func (p *PullRequestLinks) GetPatchURL() string {
+	if p == nil || p.PatchURL == nil {
+		return ""
+	}
+	return *p.PatchURL
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (p *PullRequestLinks) GetURL() string {
+	if p == nil || p.URL == nil {
+		return ""
+	}
+	return *p.URL
+}
+
+// GetMerged returns the Merged field if it's non-nil, zero value otherwise.
+func (p *PullRequestMergeResult) GetMerged() bool {
+	if p == nil || p.Merged == nil {
+		return false
+	}
+	return *p.Merged
+}
+
+// GetMessage returns the Message field if it's non-nil, zero value otherwise.
+func (p *PullRequestMergeResult) GetMessage() string {
+	if p == nil || p.Message == nil {
+		return ""
+	}
+	return *p.Message
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (p *PullRequestMergeResult) GetSHA() string {
+	if p == nil || p.SHA == nil {
+		return ""
+	}
+	return *p.SHA
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (p *PullRequestReview) GetBody() string {
+	if p == nil || p.Body == nil {
+		return ""
+	}
+	return *p.Body
+}
+
+// GetCommitID returns the CommitID field if it's non-nil, zero value otherwise.
+func (p *PullRequestReview) GetCommitID() string {
+	if p == nil || p.CommitID == nil {
+		return ""
+	}
+	return *p.CommitID
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (p *PullRequestReview) GetHTMLURL() string {
+	if p == nil || p.HTMLURL == nil {
+		return ""
+	}
+	return *p.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (p *PullRequestReview) GetID() int64 {
+	if p == nil || p.ID == nil {
+		return 0
+	}
+	return *p.ID
+}
+
+// GetPullRequestURL returns the PullRequestURL field if it's non-nil, zero value otherwise.
+func (p *PullRequestReview) GetPullRequestURL() string {
+	if p == nil || p.PullRequestURL == nil {
+		return ""
+	}
+	return *p.PullRequestURL
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (p *PullRequestReview) GetState() string {
+	if p == nil || p.State == nil {
+		return ""
+	}
+	return *p.State
+}
+
+// GetSubmittedAt returns the SubmittedAt field if it's non-nil, zero value otherwise.
+func (p *PullRequestReview) GetSubmittedAt() time.Time {
+	if p == nil || p.SubmittedAt == nil {
+		return time.Time{}
+	}
+	return *p.SubmittedAt
+}
+
+// GetUser returns the User field.
+func (p *PullRequestReview) GetUser() *User {
+	if p == nil {
+		return nil
+	}
+	return p.User
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (p *PullRequestReviewCommentEvent) GetAction() string {
+	if p == nil || p.Action == nil {
+		return ""
+	}
+	return *p.Action
+}
+
+// GetChanges returns the Changes field.
+func (p *PullRequestReviewCommentEvent) GetChanges() *EditChange {
+	if p == nil {
+		return nil
+	}
+	return p.Changes
+}
+
+// GetComment returns the Comment field.
+func (p *PullRequestReviewCommentEvent) GetComment() *PullRequestComment {
+	if p == nil {
+		return nil
+	}
+	return p.Comment
+}
+
+// GetInstallation returns the Installation field.
+func (p *PullRequestReviewCommentEvent) GetInstallation() *Installation {
+	if p == nil {
+		return nil
+	}
+	return p.Installation
+}
+
+// GetPullRequest returns the PullRequest field.
+func (p *PullRequestReviewCommentEvent) GetPullRequest() *PullRequest {
+	if p == nil {
+		return nil
+	}
+	return p.PullRequest
+}
+
+// GetRepo returns the Repo field.
+func (p *PullRequestReviewCommentEvent) GetRepo() *Repository {
+	if p == nil {
+		return nil
+	}
+	return p.Repo
+}
+
+// GetSender returns the Sender field.
+func (p *PullRequestReviewCommentEvent) GetSender() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Sender
+}
+
+// GetMessage returns the Message field if it's non-nil, zero value otherwise.
+func (p *PullRequestReviewDismissalRequest) GetMessage() string {
+	if p == nil || p.Message == nil {
+		return ""
+	}
+	return *p.Message
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (p *PullRequestReviewEvent) GetAction() string {
+	if p == nil || p.Action == nil {
+		return ""
+	}
+	return *p.Action
+}
+
+// GetInstallation returns the Installation field.
+func (p *PullRequestReviewEvent) GetInstallation() *Installation {
+	if p == nil {
+		return nil
+	}
+	return p.Installation
+}
+
+// GetOrganization returns the Organization field.
+func (p *PullRequestReviewEvent) GetOrganization() *Organization {
+	if p == nil {
+		return nil
+	}
+	return p.Organization
+}
+
+// GetPullRequest returns the PullRequest field.
+func (p *PullRequestReviewEvent) GetPullRequest() *PullRequest {
+	if p == nil {
+		return nil
+	}
+	return p.PullRequest
+}
+
+// GetRepo returns the Repo field.
+func (p *PullRequestReviewEvent) GetRepo() *Repository {
+	if p == nil {
+		return nil
+	}
+	return p.Repo
+}
+
+// GetReview returns the Review field.
+func (p *PullRequestReviewEvent) GetReview() *PullRequestReview {
+	if p == nil {
+		return nil
+	}
+	return p.Review
+}
+
+// GetSender returns the Sender field.
+func (p *PullRequestReviewEvent) GetSender() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Sender
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (p *PullRequestReviewRequest) GetBody() string {
+	if p == nil || p.Body == nil {
+		return ""
+	}
+	return *p.Body
+}
+
+// GetCommitID returns the CommitID field if it's non-nil, zero value otherwise.
+func (p *PullRequestReviewRequest) GetCommitID() string {
+	if p == nil || p.CommitID == nil {
+		return ""
+	}
+	return *p.CommitID
+}
+
+// GetEvent returns the Event field if it's non-nil, zero value otherwise.
+func (p *PullRequestReviewRequest) GetEvent() string {
+	if p == nil || p.Event == nil {
+		return ""
+	}
+	return *p.Event
+}
+
+// GetDismissalRestrictionsRequest returns the DismissalRestrictionsRequest field.
+func (p *PullRequestReviewsEnforcementRequest) GetDismissalRestrictionsRequest() *DismissalRestrictionsRequest {
+	if p == nil {
+		return nil
+	}
+	return p.DismissalRestrictionsRequest
+}
+
+// GetDismissalRestrictionsRequest returns the DismissalRestrictionsRequest field.
+func (p *PullRequestReviewsEnforcementUpdate) GetDismissalRestrictionsRequest() *DismissalRestrictionsRequest {
+	if p == nil {
+		return nil
+	}
+	return p.DismissalRestrictionsRequest
+}
+
+// GetDismissStaleReviews returns the DismissStaleReviews field if it's non-nil, zero value otherwise.
+func (p *PullRequestReviewsEnforcementUpdate) GetDismissStaleReviews() bool {
+	if p == nil || p.DismissStaleReviews == nil {
+		return false
+	}
+	return *p.DismissStaleReviews
+}
+
+// GetMergablePulls returns the MergablePulls field if it's non-nil, zero value otherwise.
+func (p *PullStats) GetMergablePulls() int {
+	if p == nil || p.MergablePulls == nil {
+		return 0
+	}
+	return *p.MergablePulls
+}
+
+// GetMergedPulls returns the MergedPulls field if it's non-nil, zero value otherwise.
+func (p *PullStats) GetMergedPulls() int {
+	if p == nil || p.MergedPulls == nil {
+		return 0
+	}
+	return *p.MergedPulls
+}
+
+// GetTotalPulls returns the TotalPulls field if it's non-nil, zero value otherwise.
+func (p *PullStats) GetTotalPulls() int {
+	if p == nil || p.TotalPulls == nil {
+		return 0
+	}
+	return *p.TotalPulls
+}
+
+// GetUnmergablePulls returns the UnmergablePulls field if it's non-nil, zero value otherwise.
+func (p *PullStats) GetUnmergablePulls() int {
+	if p == nil || p.UnmergablePulls == nil {
+		return 0
+	}
+	return *p.UnmergablePulls
+}
+
+// GetCommits returns the Commits field if it's non-nil, zero value otherwise.
+func (p *PunchCard) GetCommits() int {
+	if p == nil || p.Commits == nil {
+		return 0
+	}
+	return *p.Commits
+}
+
+// GetDay returns the Day field if it's non-nil, zero value otherwise.
+func (p *PunchCard) GetDay() int {
+	if p == nil || p.Day == nil {
+		return 0
+	}
+	return *p.Day
+}
+
+// GetHour returns the Hour field if it's non-nil, zero value otherwise.
+func (p *PunchCard) GetHour() int {
+	if p == nil || p.Hour == nil {
+		return 0
+	}
+	return *p.Hour
+}
+
+// GetAfter returns the After field if it's non-nil, zero value otherwise.
+func (p *PushEvent) GetAfter() string {
+	if p == nil || p.After == nil {
+		return ""
+	}
+	return *p.After
+}
+
+// GetBaseRef returns the BaseRef field if it's non-nil, zero value otherwise.
+func (p *PushEvent) GetBaseRef() string {
+	if p == nil || p.BaseRef == nil {
+		return ""
+	}
+	return *p.BaseRef
+}
+
+// GetBefore returns the Before field if it's non-nil, zero value otherwise.
+func (p *PushEvent) GetBefore() string {
+	if p == nil || p.Before == nil {
+		return ""
+	}
+	return *p.Before
+}
+
+// GetCompare returns the Compare field if it's non-nil, zero value otherwise.
+func (p *PushEvent) GetCompare() string {
+	if p == nil || p.Compare == nil {
+		return ""
+	}
+	return *p.Compare
+}
+
+// GetCreated returns the Created field if it's non-nil, zero value otherwise.
+func (p *PushEvent) GetCreated() bool {
+	if p == nil || p.Created == nil {
+		return false
+	}
+	return *p.Created
+}
+
+// GetDeleted returns the Deleted field if it's non-nil, zero value otherwise.
+func (p *PushEvent) GetDeleted() bool {
+	if p == nil || p.Deleted == nil {
+		return false
+	}
+	return *p.Deleted
+}
+
+// GetDistinctSize returns the DistinctSize field if it's non-nil, zero value otherwise.
+func (p *PushEvent) GetDistinctSize() int {
+	if p == nil || p.DistinctSize == nil {
+		return 0
+	}
+	return *p.DistinctSize
+}
+
+// GetForced returns the Forced field if it's non-nil, zero value otherwise.
+func (p *PushEvent) GetForced() bool {
+	if p == nil || p.Forced == nil {
+		return false
+	}
+	return *p.Forced
+}
+
+// GetHead returns the Head field if it's non-nil, zero value otherwise.
+func (p *PushEvent) GetHead() string {
+	if p == nil || p.Head == nil {
+		return ""
+	}
+	return *p.Head
+}
+
+// GetHeadCommit returns the HeadCommit field.
+func (p *PushEvent) GetHeadCommit() *PushEventCommit {
+	if p == nil {
+		return nil
+	}
+	return p.HeadCommit
+}
+
+// GetInstallation returns the Installation field.
+func (p *PushEvent) GetInstallation() *Installation {
+	if p == nil {
+		return nil
+	}
+	return p.Installation
+}
+
+// GetPusher returns the Pusher field.
+func (p *PushEvent) GetPusher() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Pusher
+}
+
+// GetPushID returns the PushID field if it's non-nil, zero value otherwise.
+func (p *PushEvent) GetPushID() int64 {
+	if p == nil || p.PushID == nil {
+		return 0
+	}
+	return *p.PushID
+}
+
+// GetRef returns the Ref field if it's non-nil, zero value otherwise.
+func (p *PushEvent) GetRef() string {
+	if p == nil || p.Ref == nil {
+		return ""
+	}
+	return *p.Ref
+}
+
+// GetRepo returns the Repo field.
+func (p *PushEvent) GetRepo() *PushEventRepository {
+	if p == nil {
+		return nil
+	}
+	return p.Repo
+}
+
+// GetSender returns the Sender field.
+func (p *PushEvent) GetSender() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Sender
+}
+
+// GetSize returns the Size field if it's non-nil, zero value otherwise.
+func (p *PushEvent) GetSize() int {
+	if p == nil || p.Size == nil {
+		return 0
+	}
+	return *p.Size
+}
+
+// GetAuthor returns the Author field.
+func (p *PushEventCommit) GetAuthor() *CommitAuthor {
+	if p == nil {
+		return nil
+	}
+	return p.Author
+}
+
+// GetCommitter returns the Committer field.
+func (p *PushEventCommit) GetCommitter() *CommitAuthor {
+	if p == nil {
+		return nil
+	}
+	return p.Committer
+}
+
+// GetDistinct returns the Distinct field if it's non-nil, zero value otherwise.
+func (p *PushEventCommit) GetDistinct() bool {
+	if p == nil || p.Distinct == nil {
+		return false
+	}
+	return *p.Distinct
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (p *PushEventCommit) GetID() string {
+	if p == nil || p.ID == nil {
+		return ""
+	}
+	return *p.ID
+}
+
+// GetMessage returns the Message field if it's non-nil, zero value otherwise.
+func (p *PushEventCommit) GetMessage() string {
+	if p == nil || p.Message == nil {
+		return ""
+	}
+	return *p.Message
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (p *PushEventCommit) GetSHA() string {
+	if p == nil || p.SHA == nil {
+		return ""
+	}
+	return *p.SHA
+}
+
+// GetTimestamp returns the Timestamp field if it's non-nil, zero value otherwise.
+func (p *PushEventCommit) GetTimestamp() Timestamp {
+	if p == nil || p.Timestamp == nil {
+		return Timestamp{}
+	}
+	return *p.Timestamp
+}
+
+// GetTreeID returns the TreeID field if it's non-nil, zero value otherwise.
+func (p *PushEventCommit) GetTreeID() string {
+	if p == nil || p.TreeID == nil {
+		return ""
+	}
+	return *p.TreeID
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (p *PushEventCommit) GetURL() string {
+	if p == nil || p.URL == nil {
+		return ""
+	}
+	return *p.URL
+}
+
+// GetEmail returns the Email field if it's non-nil, zero value otherwise.
+func (p *PushEventRepoOwner) GetEmail() string {
+	if p == nil || p.Email == nil {
+		return ""
+	}
+	return *p.Email
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (p *PushEventRepoOwner) GetName() string {
+	if p == nil || p.Name == nil {
+		return ""
+	}
+	return *p.Name
+}
+
+// GetArchiveURL returns the ArchiveURL field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetArchiveURL() string {
+	if p == nil || p.ArchiveURL == nil {
+		return ""
+	}
+	return *p.ArchiveURL
+}
+
+// GetCloneURL returns the CloneURL field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetCloneURL() string {
+	if p == nil || p.CloneURL == nil {
+		return ""
+	}
+	return *p.CloneURL
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetCreatedAt() Timestamp {
+	if p == nil || p.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *p.CreatedAt
+}
+
+// GetDefaultBranch returns the DefaultBranch field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetDefaultBranch() string {
+	if p == nil || p.DefaultBranch == nil {
+		return ""
+	}
+	return *p.DefaultBranch
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetDescription() string {
+	if p == nil || p.Description == nil {
+		return ""
+	}
+	return *p.Description
+}
+
+// GetFork returns the Fork field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetFork() bool {
+	if p == nil || p.Fork == nil {
+		return false
+	}
+	return *p.Fork
+}
+
+// GetForksCount returns the ForksCount field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetForksCount() int {
+	if p == nil || p.ForksCount == nil {
+		return 0
+	}
+	return *p.ForksCount
+}
+
+// GetFullName returns the FullName field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetFullName() string {
+	if p == nil || p.FullName == nil {
+		return ""
+	}
+	return *p.FullName
+}
+
+// GetGitURL returns the GitURL field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetGitURL() string {
+	if p == nil || p.GitURL == nil {
+		return ""
+	}
+	return *p.GitURL
+}
+
+// GetHasDownloads returns the HasDownloads field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetHasDownloads() bool {
+	if p == nil || p.HasDownloads == nil {
+		return false
+	}
+	return *p.HasDownloads
+}
+
+// GetHasIssues returns the HasIssues field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetHasIssues() bool {
+	if p == nil || p.HasIssues == nil {
+		return false
+	}
+	return *p.HasIssues
+}
+
+// GetHasPages returns the HasPages field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetHasPages() bool {
+	if p == nil || p.HasPages == nil {
+		return false
+	}
+	return *p.HasPages
+}
+
+// GetHasWiki returns the HasWiki field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetHasWiki() bool {
+	if p == nil || p.HasWiki == nil {
+		return false
+	}
+	return *p.HasWiki
+}
+
+// GetHomepage returns the Homepage field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetHomepage() string {
+	if p == nil || p.Homepage == nil {
+		return ""
+	}
+	return *p.Homepage
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetHTMLURL() string {
+	if p == nil || p.HTMLURL == nil {
+		return ""
+	}
+	return *p.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetID() int64 {
+	if p == nil || p.ID == nil {
+		return 0
+	}
+	return *p.ID
+}
+
+// GetLanguage returns the Language field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetLanguage() string {
+	if p == nil || p.Language == nil {
+		return ""
+	}
+	return *p.Language
+}
+
+// GetMasterBranch returns the MasterBranch field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetMasterBranch() string {
+	if p == nil || p.MasterBranch == nil {
+		return ""
+	}
+	return *p.MasterBranch
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetName() string {
+	if p == nil || p.Name == nil {
+		return ""
+	}
+	return *p.Name
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetNodeID() string {
+	if p == nil || p.NodeID == nil {
+		return ""
+	}
+	return *p.NodeID
+}
+
+// GetOpenIssuesCount returns the OpenIssuesCount field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetOpenIssuesCount() int {
+	if p == nil || p.OpenIssuesCount == nil {
+		return 0
+	}
+	return *p.OpenIssuesCount
+}
+
+// GetOrganization returns the Organization field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetOrganization() string {
+	if p == nil || p.Organization == nil {
+		return ""
+	}
+	return *p.Organization
+}
+
+// GetOwner returns the Owner field.
+func (p *PushEventRepository) GetOwner() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Owner
+}
+
+// GetPrivate returns the Private field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetPrivate() bool {
+	if p == nil || p.Private == nil {
+		return false
+	}
+	return *p.Private
+}
+
+// GetPushedAt returns the PushedAt field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetPushedAt() Timestamp {
+	if p == nil || p.PushedAt == nil {
+		return Timestamp{}
+	}
+	return *p.PushedAt
+}
+
+// GetSize returns the Size field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetSize() int {
+	if p == nil || p.Size == nil {
+		return 0
+	}
+	return *p.Size
+}
+
+// GetSSHURL returns the SSHURL field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetSSHURL() string {
+	if p == nil || p.SSHURL == nil {
+		return ""
+	}
+	return *p.SSHURL
+}
+
+// GetStargazersCount returns the StargazersCount field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetStargazersCount() int {
+	if p == nil || p.StargazersCount == nil {
+		return 0
+	}
+	return *p.StargazersCount
+}
+
+// GetStatusesURL returns the StatusesURL field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetStatusesURL() string {
+	if p == nil || p.StatusesURL == nil {
+		return ""
+	}
+	return *p.StatusesURL
+}
+
+// GetSVNURL returns the SVNURL field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetSVNURL() string {
+	if p == nil || p.SVNURL == nil {
+		return ""
+	}
+	return *p.SVNURL
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetUpdatedAt() Timestamp {
+	if p == nil || p.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *p.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetURL() string {
+	if p == nil || p.URL == nil {
+		return ""
+	}
+	return *p.URL
+}
+
+// GetWatchersCount returns the WatchersCount field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetWatchersCount() int {
+	if p == nil || p.WatchersCount == nil {
+		return 0
+	}
+	return *p.WatchersCount
+}
+
+// GetCore returns the Core field.
+func (r *RateLimits) GetCore() *Rate {
+	if r == nil {
+		return nil
+	}
+	return r.Core
+}
+
+// GetSearch returns the Search field.
+func (r *RateLimits) GetSearch() *Rate {
+	if r == nil {
+		return nil
+	}
+	return r.Search
+}
+
+// GetContent returns the Content field if it's non-nil, zero value otherwise.
+func (r *Reaction) GetContent() string {
+	if r == nil || r.Content == nil {
+		return ""
+	}
+	return *r.Content
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (r *Reaction) GetID() int64 {
+	if r == nil || r.ID == nil {
+		return 0
+	}
+	return *r.ID
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (r *Reaction) GetNodeID() string {
+	if r == nil || r.NodeID == nil {
+		return ""
+	}
+	return *r.NodeID
+}
+
+// GetUser returns the User field.
+func (r *Reaction) GetUser() *User {
+	if r == nil {
+		return nil
+	}
+	return r.User
+}
+
+// GetConfused returns the Confused field if it's non-nil, zero value otherwise.
+func (r *Reactions) GetConfused() int {
+	if r == nil || r.Confused == nil {
+		return 0
+	}
+	return *r.Confused
+}
+
+// GetHeart returns the Heart field if it's non-nil, zero value otherwise.
+func (r *Reactions) GetHeart() int {
+	if r == nil || r.Heart == nil {
+		return 0
+	}
+	return *r.Heart
+}
+
+// GetHooray returns the Hooray field if it's non-nil, zero value otherwise.
+func (r *Reactions) GetHooray() int {
+	if r == nil || r.Hooray == nil {
+		return 0
+	}
+	return *r.Hooray
+}
+
+// GetLaugh returns the Laugh field if it's non-nil, zero value otherwise.
+func (r *Reactions) GetLaugh() int {
+	if r == nil || r.Laugh == nil {
+		return 0
+	}
+	return *r.Laugh
+}
+
+// GetMinusOne returns the MinusOne field if it's non-nil, zero value otherwise.
+func (r *Reactions) GetMinusOne() int {
+	if r == nil || r.MinusOne == nil {
+		return 0
+	}
+	return *r.MinusOne
+}
+
+// GetPlusOne returns the PlusOne field if it's non-nil, zero value otherwise.
+func (r *Reactions) GetPlusOne() int {
+	if r == nil || r.PlusOne == nil {
+		return 0
+	}
+	return *r.PlusOne
+}
+
+// GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise.
+func (r *Reactions) GetTotalCount() int {
+	if r == nil || r.TotalCount == nil {
+		return 0
+	}
+	return *r.TotalCount
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (r *Reactions) GetURL() string {
+	if r == nil || r.URL == nil {
+		return ""
+	}
+	return *r.URL
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (r *Reference) GetNodeID() string {
+	if r == nil || r.NodeID == nil {
+		return ""
+	}
+	return *r.NodeID
+}
+
+// GetObject returns the Object field.
+func (r *Reference) GetObject() *GitObject {
+	if r == nil {
+		return nil
+	}
+	return r.Object
+}
+
+// GetRef returns the Ref field if it's non-nil, zero value otherwise.
+func (r *Reference) GetRef() string {
+	if r == nil || r.Ref == nil {
+		return ""
+	}
+	return *r.Ref
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (r *Reference) GetURL() string {
+	if r == nil || r.URL == nil {
+		return ""
+	}
+	return *r.URL
+}
+
+// GetBrowserDownloadURL returns the BrowserDownloadURL field if it's non-nil, zero value otherwise.
+func (r *ReleaseAsset) GetBrowserDownloadURL() string {
+	if r == nil || r.BrowserDownloadURL == nil {
+		return ""
+	}
+	return *r.BrowserDownloadURL
+}
+
+// GetContentType returns the ContentType field if it's non-nil, zero value otherwise.
+func (r *ReleaseAsset) GetContentType() string {
+	if r == nil || r.ContentType == nil {
+		return ""
+	}
+	return *r.ContentType
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (r *ReleaseAsset) GetCreatedAt() Timestamp {
+	if r == nil || r.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *r.CreatedAt
+}
+
+// GetDownloadCount returns the DownloadCount field if it's non-nil, zero value otherwise.
+func (r *ReleaseAsset) GetDownloadCount() int {
+	if r == nil || r.DownloadCount == nil {
+		return 0
+	}
+	return *r.DownloadCount
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (r *ReleaseAsset) GetID() int64 {
+	if r == nil || r.ID == nil {
+		return 0
+	}
+	return *r.ID
+}
+
+// GetLabel returns the Label field if it's non-nil, zero value otherwise.
+func (r *ReleaseAsset) GetLabel() string {
+	if r == nil || r.Label == nil {
+		return ""
+	}
+	return *r.Label
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (r *ReleaseAsset) GetName() string {
+	if r == nil || r.Name == nil {
+		return ""
+	}
+	return *r.Name
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (r *ReleaseAsset) GetNodeID() string {
+	if r == nil || r.NodeID == nil {
+		return ""
+	}
+	return *r.NodeID
+}
+
+// GetSize returns the Size field if it's non-nil, zero value otherwise.
+func (r *ReleaseAsset) GetSize() int {
+	if r == nil || r.Size == nil {
+		return 0
+	}
+	return *r.Size
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (r *ReleaseAsset) GetState() string {
+	if r == nil || r.State == nil {
+		return ""
+	}
+	return *r.State
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (r *ReleaseAsset) GetUpdatedAt() Timestamp {
+	if r == nil || r.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *r.UpdatedAt
+}
+
+// GetUploader returns the Uploader field.
+func (r *ReleaseAsset) GetUploader() *User {
+	if r == nil {
+		return nil
+	}
+	return r.Uploader
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (r *ReleaseAsset) GetURL() string {
+	if r == nil || r.URL == nil {
+		return ""
+	}
+	return *r.URL
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (r *ReleaseEvent) GetAction() string {
+	if r == nil || r.Action == nil {
+		return ""
+	}
+	return *r.Action
+}
+
+// GetInstallation returns the Installation field.
+func (r *ReleaseEvent) GetInstallation() *Installation {
+	if r == nil {
+		return nil
+	}
+	return r.Installation
+}
+
+// GetRelease returns the Release field.
+func (r *ReleaseEvent) GetRelease() *RepositoryRelease {
+	if r == nil {
+		return nil
+	}
+	return r.Release
+}
+
+// GetRepo returns the Repo field.
+func (r *ReleaseEvent) GetRepo() *Repository {
+	if r == nil {
+		return nil
+	}
+	return r.Repo
+}
+
+// GetSender returns the Sender field.
+func (r *ReleaseEvent) GetSender() *User {
+	if r == nil {
+		return nil
+	}
+	return r.Sender
+}
+
+// GetFrom returns the From field if it's non-nil, zero value otherwise.
+func (r *Rename) GetFrom() string {
+	if r == nil || r.From == nil {
+		return ""
+	}
+	return *r.From
+}
+
+// GetTo returns the To field if it's non-nil, zero value otherwise.
+func (r *Rename) GetTo() string {
+	if r == nil || r.To == nil {
+		return ""
+	}
+	return *r.To
+}
+
+// GetIncompleteResults returns the IncompleteResults field if it's non-nil, zero value otherwise.
+func (r *RepositoriesSearchResult) GetIncompleteResults() bool {
+	if r == nil || r.IncompleteResults == nil {
+		return false
+	}
+	return *r.IncompleteResults
+}
+
+// GetTotal returns the Total field if it's non-nil, zero value otherwise.
+func (r *RepositoriesSearchResult) GetTotal() int {
+	if r == nil || r.Total == nil {
+		return 0
+	}
+	return *r.Total
+}
+
+// GetAllowMergeCommit returns the AllowMergeCommit field if it's non-nil, zero value otherwise.
+func (r *Repository) GetAllowMergeCommit() bool {
+	if r == nil || r.AllowMergeCommit == nil {
+		return false
+	}
+	return *r.AllowMergeCommit
+}
+
+// GetAllowRebaseMerge returns the AllowRebaseMerge field if it's non-nil, zero value otherwise.
+func (r *Repository) GetAllowRebaseMerge() bool {
+	if r == nil || r.AllowRebaseMerge == nil {
+		return false
+	}
+	return *r.AllowRebaseMerge
+}
+
+// GetAllowSquashMerge returns the AllowSquashMerge field if it's non-nil, zero value otherwise.
+func (r *Repository) GetAllowSquashMerge() bool {
+	if r == nil || r.AllowSquashMerge == nil {
+		return false
+	}
+	return *r.AllowSquashMerge
+}
+
+// GetArchived returns the Archived field if it's non-nil, zero value otherwise.
+func (r *Repository) GetArchived() bool {
+	if r == nil || r.Archived == nil {
+		return false
+	}
+	return *r.Archived
+}
+
+// GetArchiveURL returns the ArchiveURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetArchiveURL() string {
+	if r == nil || r.ArchiveURL == nil {
+		return ""
+	}
+	return *r.ArchiveURL
+}
+
+// GetAssigneesURL returns the AssigneesURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetAssigneesURL() string {
+	if r == nil || r.AssigneesURL == nil {
+		return ""
+	}
+	return *r.AssigneesURL
+}
+
+// GetAutoInit returns the AutoInit field if it's non-nil, zero value otherwise.
+func (r *Repository) GetAutoInit() bool {
+	if r == nil || r.AutoInit == nil {
+		return false
+	}
+	return *r.AutoInit
+}
+
+// GetBlobsURL returns the BlobsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetBlobsURL() string {
+	if r == nil || r.BlobsURL == nil {
+		return ""
+	}
+	return *r.BlobsURL
+}
+
+// GetBranchesURL returns the BranchesURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetBranchesURL() string {
+	if r == nil || r.BranchesURL == nil {
+		return ""
+	}
+	return *r.BranchesURL
+}
+
+// GetCloneURL returns the CloneURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetCloneURL() string {
+	if r == nil || r.CloneURL == nil {
+		return ""
+	}
+	return *r.CloneURL
+}
+
+// GetCodeOfConduct returns the CodeOfConduct field.
+func (r *Repository) GetCodeOfConduct() *CodeOfConduct {
+	if r == nil {
+		return nil
+	}
+	return r.CodeOfConduct
+}
+
+// GetCollaboratorsURL returns the CollaboratorsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetCollaboratorsURL() string {
+	if r == nil || r.CollaboratorsURL == nil {
+		return ""
+	}
+	return *r.CollaboratorsURL
+}
+
+// GetCommentsURL returns the CommentsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetCommentsURL() string {
+	if r == nil || r.CommentsURL == nil {
+		return ""
+	}
+	return *r.CommentsURL
+}
+
+// GetCommitsURL returns the CommitsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetCommitsURL() string {
+	if r == nil || r.CommitsURL == nil {
+		return ""
+	}
+	return *r.CommitsURL
+}
+
+// GetCompareURL returns the CompareURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetCompareURL() string {
+	if r == nil || r.CompareURL == nil {
+		return ""
+	}
+	return *r.CompareURL
+}
+
+// GetContentsURL returns the ContentsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetContentsURL() string {
+	if r == nil || r.ContentsURL == nil {
+		return ""
+	}
+	return *r.ContentsURL
+}
+
+// GetContributorsURL returns the ContributorsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetContributorsURL() string {
+	if r == nil || r.ContributorsURL == nil {
+		return ""
+	}
+	return *r.ContributorsURL
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (r *Repository) GetCreatedAt() Timestamp {
+	if r == nil || r.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *r.CreatedAt
+}
+
+// GetDefaultBranch returns the DefaultBranch field if it's non-nil, zero value otherwise.
+func (r *Repository) GetDefaultBranch() string {
+	if r == nil || r.DefaultBranch == nil {
+		return ""
+	}
+	return *r.DefaultBranch
+}
+
+// GetDeploymentsURL returns the DeploymentsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetDeploymentsURL() string {
+	if r == nil || r.DeploymentsURL == nil {
+		return ""
+	}
+	return *r.DeploymentsURL
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (r *Repository) GetDescription() string {
+	if r == nil || r.Description == nil {
+		return ""
+	}
+	return *r.Description
+}
+
+// GetDownloadsURL returns the DownloadsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetDownloadsURL() string {
+	if r == nil || r.DownloadsURL == nil {
+		return ""
+	}
+	return *r.DownloadsURL
+}
+
+// GetEventsURL returns the EventsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetEventsURL() string {
+	if r == nil || r.EventsURL == nil {
+		return ""
+	}
+	return *r.EventsURL
+}
+
+// GetFork returns the Fork field if it's non-nil, zero value otherwise.
+func (r *Repository) GetFork() bool {
+	if r == nil || r.Fork == nil {
+		return false
+	}
+	return *r.Fork
+}
+
+// GetForksCount returns the ForksCount field if it's non-nil, zero value otherwise.
+func (r *Repository) GetForksCount() int {
+	if r == nil || r.ForksCount == nil {
+		return 0
+	}
+	return *r.ForksCount
+}
+
+// GetForksURL returns the ForksURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetForksURL() string {
+	if r == nil || r.ForksURL == nil {
+		return ""
+	}
+	return *r.ForksURL
+}
+
+// GetFullName returns the FullName field if it's non-nil, zero value otherwise.
+func (r *Repository) GetFullName() string {
+	if r == nil || r.FullName == nil {
+		return ""
+	}
+	return *r.FullName
+}
+
+// GetGitCommitsURL returns the GitCommitsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetGitCommitsURL() string {
+	if r == nil || r.GitCommitsURL == nil {
+		return ""
+	}
+	return *r.GitCommitsURL
+}
+
+// GetGitignoreTemplate returns the GitignoreTemplate field if it's non-nil, zero value otherwise.
+func (r *Repository) GetGitignoreTemplate() string {
+	if r == nil || r.GitignoreTemplate == nil {
+		return ""
+	}
+	return *r.GitignoreTemplate
+}
+
+// GetGitRefsURL returns the GitRefsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetGitRefsURL() string {
+	if r == nil || r.GitRefsURL == nil {
+		return ""
+	}
+	return *r.GitRefsURL
+}
+
+// GetGitTagsURL returns the GitTagsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetGitTagsURL() string {
+	if r == nil || r.GitTagsURL == nil {
+		return ""
+	}
+	return *r.GitTagsURL
+}
+
+// GetGitURL returns the GitURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetGitURL() string {
+	if r == nil || r.GitURL == nil {
+		return ""
+	}
+	return *r.GitURL
+}
+
+// GetHasDownloads returns the HasDownloads field if it's non-nil, zero value otherwise.
+func (r *Repository) GetHasDownloads() bool {
+	if r == nil || r.HasDownloads == nil {
+		return false
+	}
+	return *r.HasDownloads
+}
+
+// GetHasIssues returns the HasIssues field if it's non-nil, zero value otherwise.
+func (r *Repository) GetHasIssues() bool {
+	if r == nil || r.HasIssues == nil {
+		return false
+	}
+	return *r.HasIssues
+}
+
+// GetHasPages returns the HasPages field if it's non-nil, zero value otherwise.
+func (r *Repository) GetHasPages() bool {
+	if r == nil || r.HasPages == nil {
+		return false
+	}
+	return *r.HasPages
+}
+
+// GetHasProjects returns the HasProjects field if it's non-nil, zero value otherwise.
+func (r *Repository) GetHasProjects() bool {
+	if r == nil || r.HasProjects == nil {
+		return false
+	}
+	return *r.HasProjects
+}
+
+// GetHasWiki returns the HasWiki field if it's non-nil, zero value otherwise.
+func (r *Repository) GetHasWiki() bool {
+	if r == nil || r.HasWiki == nil {
+		return false
+	}
+	return *r.HasWiki
+}
+
+// GetHomepage returns the Homepage field if it's non-nil, zero value otherwise.
+func (r *Repository) GetHomepage() string {
+	if r == nil || r.Homepage == nil {
+		return ""
+	}
+	return *r.Homepage
+}
+
+// GetHooksURL returns the HooksURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetHooksURL() string {
+	if r == nil || r.HooksURL == nil {
+		return ""
+	}
+	return *r.HooksURL
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetHTMLURL() string {
+	if r == nil || r.HTMLURL == nil {
+		return ""
+	}
+	return *r.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (r *Repository) GetID() int64 {
+	if r == nil || r.ID == nil {
+		return 0
+	}
+	return *r.ID
+}
+
+// GetIssueCommentURL returns the IssueCommentURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetIssueCommentURL() string {
+	if r == nil || r.IssueCommentURL == nil {
+		return ""
+	}
+	return *r.IssueCommentURL
+}
+
+// GetIssueEventsURL returns the IssueEventsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetIssueEventsURL() string {
+	if r == nil || r.IssueEventsURL == nil {
+		return ""
+	}
+	return *r.IssueEventsURL
+}
+
+// GetIssuesURL returns the IssuesURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetIssuesURL() string {
+	if r == nil || r.IssuesURL == nil {
+		return ""
+	}
+	return *r.IssuesURL
+}
+
+// GetKeysURL returns the KeysURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetKeysURL() string {
+	if r == nil || r.KeysURL == nil {
+		return ""
+	}
+	return *r.KeysURL
+}
+
+// GetLabelsURL returns the LabelsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetLabelsURL() string {
+	if r == nil || r.LabelsURL == nil {
+		return ""
+	}
+	return *r.LabelsURL
+}
+
+// GetLanguage returns the Language field if it's non-nil, zero value otherwise.
+func (r *Repository) GetLanguage() string {
+	if r == nil || r.Language == nil {
+		return ""
+	}
+	return *r.Language
+}
+
+// GetLanguagesURL returns the LanguagesURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetLanguagesURL() string {
+	if r == nil || r.LanguagesURL == nil {
+		return ""
+	}
+	return *r.LanguagesURL
+}
+
+// GetLicense returns the License field.
+func (r *Repository) GetLicense() *License {
+	if r == nil {
+		return nil
+	}
+	return r.License
+}
+
+// GetLicenseTemplate returns the LicenseTemplate field if it's non-nil, zero value otherwise.
+func (r *Repository) GetLicenseTemplate() string {
+	if r == nil || r.LicenseTemplate == nil {
+		return ""
+	}
+	return *r.LicenseTemplate
+}
+
+// GetMasterBranch returns the MasterBranch field if it's non-nil, zero value otherwise.
+func (r *Repository) GetMasterBranch() string {
+	if r == nil || r.MasterBranch == nil {
+		return ""
+	}
+	return *r.MasterBranch
+}
+
+// GetMergesURL returns the MergesURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetMergesURL() string {
+	if r == nil || r.MergesURL == nil {
+		return ""
+	}
+	return *r.MergesURL
+}
+
+// GetMilestonesURL returns the MilestonesURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetMilestonesURL() string {
+	if r == nil || r.MilestonesURL == nil {
+		return ""
+	}
+	return *r.MilestonesURL
+}
+
+// GetMirrorURL returns the MirrorURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetMirrorURL() string {
+	if r == nil || r.MirrorURL == nil {
+		return ""
+	}
+	return *r.MirrorURL
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (r *Repository) GetName() string {
+	if r == nil || r.Name == nil {
+		return ""
+	}
+	return *r.Name
+}
+
+// GetNetworkCount returns the NetworkCount field if it's non-nil, zero value otherwise.
+func (r *Repository) GetNetworkCount() int {
+	if r == nil || r.NetworkCount == nil {
+		return 0
+	}
+	return *r.NetworkCount
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (r *Repository) GetNodeID() string {
+	if r == nil || r.NodeID == nil {
+		return ""
+	}
+	return *r.NodeID
+}
+
+// GetNotificationsURL returns the NotificationsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetNotificationsURL() string {
+	if r == nil || r.NotificationsURL == nil {
+		return ""
+	}
+	return *r.NotificationsURL
+}
+
+// GetOpenIssuesCount returns the OpenIssuesCount field if it's non-nil, zero value otherwise.
+func (r *Repository) GetOpenIssuesCount() int {
+	if r == nil || r.OpenIssuesCount == nil {
+		return 0
+	}
+	return *r.OpenIssuesCount
+}
+
+// GetOrganization returns the Organization field.
+func (r *Repository) GetOrganization() *Organization {
+	if r == nil {
+		return nil
+	}
+	return r.Organization
+}
+
+// GetOwner returns the Owner field.
+func (r *Repository) GetOwner() *User {
+	if r == nil {
+		return nil
+	}
+	return r.Owner
+}
+
+// GetParent returns the Parent field.
+func (r *Repository) GetParent() *Repository {
+	if r == nil {
+		return nil
+	}
+	return r.Parent
+}
+
+// GetPermissions returns the Permissions field if it's non-nil, zero value otherwise.
+func (r *Repository) GetPermissions() map[string]bool {
+	if r == nil || r.Permissions == nil {
+		return map[string]bool{}
+	}
+	return *r.Permissions
+}
+
+// GetPrivate returns the Private field if it's non-nil, zero value otherwise.
+func (r *Repository) GetPrivate() bool {
+	if r == nil || r.Private == nil {
+		return false
+	}
+	return *r.Private
+}
+
+// GetPullsURL returns the PullsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetPullsURL() string {
+	if r == nil || r.PullsURL == nil {
+		return ""
+	}
+	return *r.PullsURL
+}
+
+// GetPushedAt returns the PushedAt field if it's non-nil, zero value otherwise.
+func (r *Repository) GetPushedAt() Timestamp {
+	if r == nil || r.PushedAt == nil {
+		return Timestamp{}
+	}
+	return *r.PushedAt
+}
+
+// GetReleasesURL returns the ReleasesURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetReleasesURL() string {
+	if r == nil || r.ReleasesURL == nil {
+		return ""
+	}
+	return *r.ReleasesURL
+}
+
+// GetSize returns the Size field if it's non-nil, zero value otherwise.
+func (r *Repository) GetSize() int {
+	if r == nil || r.Size == nil {
+		return 0
+	}
+	return *r.Size
+}
+
+// GetSource returns the Source field.
+func (r *Repository) GetSource() *Repository {
+	if r == nil {
+		return nil
+	}
+	return r.Source
+}
+
+// GetSSHURL returns the SSHURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetSSHURL() string {
+	if r == nil || r.SSHURL == nil {
+		return ""
+	}
+	return *r.SSHURL
+}
+
+// GetStargazersCount returns the StargazersCount field if it's non-nil, zero value otherwise.
+func (r *Repository) GetStargazersCount() int {
+	if r == nil || r.StargazersCount == nil {
+		return 0
+	}
+	return *r.StargazersCount
+}
+
+// GetStargazersURL returns the StargazersURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetStargazersURL() string {
+	if r == nil || r.StargazersURL == nil {
+		return ""
+	}
+	return *r.StargazersURL
+}
+
+// GetStatusesURL returns the StatusesURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetStatusesURL() string {
+	if r == nil || r.StatusesURL == nil {
+		return ""
+	}
+	return *r.StatusesURL
+}
+
+// GetSubscribersCount returns the SubscribersCount field if it's non-nil, zero value otherwise.
+func (r *Repository) GetSubscribersCount() int {
+	if r == nil || r.SubscribersCount == nil {
+		return 0
+	}
+	return *r.SubscribersCount
+}
+
+// GetSubscribersURL returns the SubscribersURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetSubscribersURL() string {
+	if r == nil || r.SubscribersURL == nil {
+		return ""
+	}
+	return *r.SubscribersURL
+}
+
+// GetSubscriptionURL returns the SubscriptionURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetSubscriptionURL() string {
+	if r == nil || r.SubscriptionURL == nil {
+		return ""
+	}
+	return *r.SubscriptionURL
+}
+
+// GetSVNURL returns the SVNURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetSVNURL() string {
+	if r == nil || r.SVNURL == nil {
+		return ""
+	}
+	return *r.SVNURL
+}
+
+// GetTagsURL returns the TagsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetTagsURL() string {
+	if r == nil || r.TagsURL == nil {
+		return ""
+	}
+	return *r.TagsURL
+}
+
+// GetTeamID returns the TeamID field if it's non-nil, zero value otherwise.
+func (r *Repository) GetTeamID() int64 {
+	if r == nil || r.TeamID == nil {
+		return 0
+	}
+	return *r.TeamID
+}
+
+// GetTeamsURL returns the TeamsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetTeamsURL() string {
+	if r == nil || r.TeamsURL == nil {
+		return ""
+	}
+	return *r.TeamsURL
+}
+
+// GetTreesURL returns the TreesURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetTreesURL() string {
+	if r == nil || r.TreesURL == nil {
+		return ""
+	}
+	return *r.TreesURL
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (r *Repository) GetUpdatedAt() Timestamp {
+	if r == nil || r.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *r.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetURL() string {
+	if r == nil || r.URL == nil {
+		return ""
+	}
+	return *r.URL
+}
+
+// GetWatchersCount returns the WatchersCount field if it's non-nil, zero value otherwise.
+func (r *Repository) GetWatchersCount() int {
+	if r == nil || r.WatchersCount == nil {
+		return 0
+	}
+	return *r.WatchersCount
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (r *RepositoryComment) GetBody() string {
+	if r == nil || r.Body == nil {
+		return ""
+	}
+	return *r.Body
+}
+
+// GetCommitID returns the CommitID field if it's non-nil, zero value otherwise.
+func (r *RepositoryComment) GetCommitID() string {
+	if r == nil || r.CommitID == nil {
+		return ""
+	}
+	return *r.CommitID
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (r *RepositoryComment) GetCreatedAt() time.Time {
+	if r == nil || r.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *r.CreatedAt
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryComment) GetHTMLURL() string {
+	if r == nil || r.HTMLURL == nil {
+		return ""
+	}
+	return *r.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (r *RepositoryComment) GetID() int64 {
+	if r == nil || r.ID == nil {
+		return 0
+	}
+	return *r.ID
+}
+
+// GetPath returns the Path field if it's non-nil, zero value otherwise.
+func (r *RepositoryComment) GetPath() string {
+	if r == nil || r.Path == nil {
+		return ""
+	}
+	return *r.Path
+}
+
+// GetPosition returns the Position field if it's non-nil, zero value otherwise.
+func (r *RepositoryComment) GetPosition() int {
+	if r == nil || r.Position == nil {
+		return 0
+	}
+	return *r.Position
+}
+
+// GetReactions returns the Reactions field.
+func (r *RepositoryComment) GetReactions() *Reactions {
+	if r == nil {
+		return nil
+	}
+	return r.Reactions
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (r *RepositoryComment) GetUpdatedAt() time.Time {
+	if r == nil || r.UpdatedAt == nil {
+		return time.Time{}
+	}
+	return *r.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (r *RepositoryComment) GetURL() string {
+	if r == nil || r.URL == nil {
+		return ""
+	}
+	return *r.URL
+}
+
+// GetUser returns the User field.
+func (r *RepositoryComment) GetUser() *User {
+	if r == nil {
+		return nil
+	}
+	return r.User
+}
+
+// GetAuthor returns the Author field.
+func (r *RepositoryCommit) GetAuthor() *User {
+	if r == nil {
+		return nil
+	}
+	return r.Author
+}
+
+// GetCommentsURL returns the CommentsURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryCommit) GetCommentsURL() string {
+	if r == nil || r.CommentsURL == nil {
+		return ""
+	}
+	return *r.CommentsURL
+}
+
+// GetCommit returns the Commit field.
+func (r *RepositoryCommit) GetCommit() *Commit {
+	if r == nil {
+		return nil
+	}
+	return r.Commit
+}
+
+// GetCommitter returns the Committer field.
+func (r *RepositoryCommit) GetCommitter() *User {
+	if r == nil {
+		return nil
+	}
+	return r.Committer
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryCommit) GetHTMLURL() string {
+	if r == nil || r.HTMLURL == nil {
+		return ""
+	}
+	return *r.HTMLURL
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (r *RepositoryCommit) GetSHA() string {
+	if r == nil || r.SHA == nil {
+		return ""
+	}
+	return *r.SHA
+}
+
+// GetStats returns the Stats field.
+func (r *RepositoryCommit) GetStats() *CommitStats {
+	if r == nil {
+		return nil
+	}
+	return r.Stats
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (r *RepositoryCommit) GetURL() string {
+	if r == nil || r.URL == nil {
+		return ""
+	}
+	return *r.URL
+}
+
+// GetDownloadURL returns the DownloadURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryContent) GetDownloadURL() string {
+	if r == nil || r.DownloadURL == nil {
+		return ""
+	}
+	return *r.DownloadURL
+}
+
+// GetEncoding returns the Encoding field if it's non-nil, zero value otherwise.
+func (r *RepositoryContent) GetEncoding() string {
+	if r == nil || r.Encoding == nil {
+		return ""
+	}
+	return *r.Encoding
+}
+
+// GetGitURL returns the GitURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryContent) GetGitURL() string {
+	if r == nil || r.GitURL == nil {
+		return ""
+	}
+	return *r.GitURL
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryContent) GetHTMLURL() string {
+	if r == nil || r.HTMLURL == nil {
+		return ""
+	}
+	return *r.HTMLURL
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (r *RepositoryContent) GetName() string {
+	if r == nil || r.Name == nil {
+		return ""
+	}
+	return *r.Name
+}
+
+// GetPath returns the Path field if it's non-nil, zero value otherwise.
+func (r *RepositoryContent) GetPath() string {
+	if r == nil || r.Path == nil {
+		return ""
+	}
+	return *r.Path
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (r *RepositoryContent) GetSHA() string {
+	if r == nil || r.SHA == nil {
+		return ""
+	}
+	return *r.SHA
+}
+
+// GetSize returns the Size field if it's non-nil, zero value otherwise.
+func (r *RepositoryContent) GetSize() int {
+	if r == nil || r.Size == nil {
+		return 0
+	}
+	return *r.Size
+}
+
+// GetTarget returns the Target field if it's non-nil, zero value otherwise.
+func (r *RepositoryContent) GetTarget() string {
+	if r == nil || r.Target == nil {
+		return ""
+	}
+	return *r.Target
+}
+
+// GetType returns the Type field if it's non-nil, zero value otherwise.
+func (r *RepositoryContent) GetType() string {
+	if r == nil || r.Type == nil {
+		return ""
+	}
+	return *r.Type
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (r *RepositoryContent) GetURL() string {
+	if r == nil || r.URL == nil {
+		return ""
+	}
+	return *r.URL
+}
+
+// GetAuthor returns the Author field.
+func (r *RepositoryContentFileOptions) GetAuthor() *CommitAuthor {
+	if r == nil {
+		return nil
+	}
+	return r.Author
+}
+
+// GetBranch returns the Branch field if it's non-nil, zero value otherwise.
+func (r *RepositoryContentFileOptions) GetBranch() string {
+	if r == nil || r.Branch == nil {
+		return ""
+	}
+	return *r.Branch
+}
+
+// GetCommitter returns the Committer field.
+func (r *RepositoryContentFileOptions) GetCommitter() *CommitAuthor {
+	if r == nil {
+		return nil
+	}
+	return r.Committer
+}
+
+// GetMessage returns the Message field if it's non-nil, zero value otherwise.
+func (r *RepositoryContentFileOptions) GetMessage() string {
+	if r == nil || r.Message == nil {
+		return ""
+	}
+	return *r.Message
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (r *RepositoryContentFileOptions) GetSHA() string {
+	if r == nil || r.SHA == nil {
+		return ""
+	}
+	return *r.SHA
+}
+
+// GetContent returns the Content field.
+func (r *RepositoryContentResponse) GetContent() *RepositoryContent {
+	if r == nil {
+		return nil
+	}
+	return r.Content
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (r *RepositoryEvent) GetAction() string {
+	if r == nil || r.Action == nil {
+		return ""
+	}
+	return *r.Action
+}
+
+// GetInstallation returns the Installation field.
+func (r *RepositoryEvent) GetInstallation() *Installation {
+	if r == nil {
+		return nil
+	}
+	return r.Installation
+}
+
+// GetOrg returns the Org field.
+func (r *RepositoryEvent) GetOrg() *Organization {
+	if r == nil {
+		return nil
+	}
+	return r.Org
+}
+
+// GetRepo returns the Repo field.
+func (r *RepositoryEvent) GetRepo() *Repository {
+	if r == nil {
+		return nil
+	}
+	return r.Repo
+}
+
+// GetSender returns the Sender field.
+func (r *RepositoryEvent) GetSender() *User {
+	if r == nil {
+		return nil
+	}
+	return r.Sender
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (r *RepositoryInvitation) GetCreatedAt() Timestamp {
+	if r == nil || r.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *r.CreatedAt
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryInvitation) GetHTMLURL() string {
+	if r == nil || r.HTMLURL == nil {
+		return ""
+	}
+	return *r.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (r *RepositoryInvitation) GetID() int64 {
+	if r == nil || r.ID == nil {
+		return 0
+	}
+	return *r.ID
+}
+
+// GetInvitee returns the Invitee field.
+func (r *RepositoryInvitation) GetInvitee() *User {
+	if r == nil {
+		return nil
+	}
+	return r.Invitee
+}
+
+// GetInviter returns the Inviter field.
+func (r *RepositoryInvitation) GetInviter() *User {
+	if r == nil {
+		return nil
+	}
+	return r.Inviter
+}
+
+// GetPermissions returns the Permissions field if it's non-nil, zero value otherwise.
+func (r *RepositoryInvitation) GetPermissions() string {
+	if r == nil || r.Permissions == nil {
+		return ""
+	}
+	return *r.Permissions
+}
+
+// GetRepo returns the Repo field.
+func (r *RepositoryInvitation) GetRepo() *Repository {
+	if r == nil {
+		return nil
+	}
+	return r.Repo
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (r *RepositoryInvitation) GetURL() string {
+	if r == nil || r.URL == nil {
+		return ""
+	}
+	return *r.URL
+}
+
+// GetContent returns the Content field if it's non-nil, zero value otherwise.
+func (r *RepositoryLicense) GetContent() string {
+	if r == nil || r.Content == nil {
+		return ""
+	}
+	return *r.Content
+}
+
+// GetDownloadURL returns the DownloadURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryLicense) GetDownloadURL() string {
+	if r == nil || r.DownloadURL == nil {
+		return ""
+	}
+	return *r.DownloadURL
+}
+
+// GetEncoding returns the Encoding field if it's non-nil, zero value otherwise.
+func (r *RepositoryLicense) GetEncoding() string {
+	if r == nil || r.Encoding == nil {
+		return ""
+	}
+	return *r.Encoding
+}
+
+// GetGitURL returns the GitURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryLicense) GetGitURL() string {
+	if r == nil || r.GitURL == nil {
+		return ""
+	}
+	return *r.GitURL
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryLicense) GetHTMLURL() string {
+	if r == nil || r.HTMLURL == nil {
+		return ""
+	}
+	return *r.HTMLURL
+}
+
+// GetLicense returns the License field.
+func (r *RepositoryLicense) GetLicense() *License {
+	if r == nil {
+		return nil
+	}
+	return r.License
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (r *RepositoryLicense) GetName() string {
+	if r == nil || r.Name == nil {
+		return ""
+	}
+	return *r.Name
+}
+
+// GetPath returns the Path field if it's non-nil, zero value otherwise.
+func (r *RepositoryLicense) GetPath() string {
+	if r == nil || r.Path == nil {
+		return ""
+	}
+	return *r.Path
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (r *RepositoryLicense) GetSHA() string {
+	if r == nil || r.SHA == nil {
+		return ""
+	}
+	return *r.SHA
+}
+
+// GetSize returns the Size field if it's non-nil, zero value otherwise.
+func (r *RepositoryLicense) GetSize() int {
+	if r == nil || r.Size == nil {
+		return 0
+	}
+	return *r.Size
+}
+
+// GetType returns the Type field if it's non-nil, zero value otherwise.
+func (r *RepositoryLicense) GetType() string {
+	if r == nil || r.Type == nil {
+		return ""
+	}
+	return *r.Type
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (r *RepositoryLicense) GetURL() string {
+	if r == nil || r.URL == nil {
+		return ""
+	}
+	return *r.URL
+}
+
+// GetBase returns the Base field if it's non-nil, zero value otherwise.
+func (r *RepositoryMergeRequest) GetBase() string {
+	if r == nil || r.Base == nil {
+		return ""
+	}
+	return *r.Base
+}
+
+// GetCommitMessage returns the CommitMessage field if it's non-nil, zero value otherwise.
+func (r *RepositoryMergeRequest) GetCommitMessage() string {
+	if r == nil || r.CommitMessage == nil {
+		return ""
+	}
+	return *r.CommitMessage
+}
+
+// GetHead returns the Head field if it's non-nil, zero value otherwise.
+func (r *RepositoryMergeRequest) GetHead() string {
+	if r == nil || r.Head == nil {
+		return ""
+	}
+	return *r.Head
+}
+
+// GetPermission returns the Permission field if it's non-nil, zero value otherwise.
+func (r *RepositoryPermissionLevel) GetPermission() string {
+	if r == nil || r.Permission == nil {
+		return ""
+	}
+	return *r.Permission
+}
+
+// GetUser returns the User field.
+func (r *RepositoryPermissionLevel) GetUser() *User {
+	if r == nil {
+		return nil
+	}
+	return r.User
+}
+
+// GetAssetsURL returns the AssetsURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetAssetsURL() string {
+	if r == nil || r.AssetsURL == nil {
+		return ""
+	}
+	return *r.AssetsURL
+}
+
+// GetAuthor returns the Author field.
+func (r *RepositoryRelease) GetAuthor() *User {
+	if r == nil {
+		return nil
+	}
+	return r.Author
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetBody() string {
+	if r == nil || r.Body == nil {
+		return ""
+	}
+	return *r.Body
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetCreatedAt() Timestamp {
+	if r == nil || r.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *r.CreatedAt
+}
+
+// GetDraft returns the Draft field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetDraft() bool {
+	if r == nil || r.Draft == nil {
+		return false
+	}
+	return *r.Draft
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetHTMLURL() string {
+	if r == nil || r.HTMLURL == nil {
+		return ""
+	}
+	return *r.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetID() int64 {
+	if r == nil || r.ID == nil {
+		return 0
+	}
+	return *r.ID
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetName() string {
+	if r == nil || r.Name == nil {
+		return ""
+	}
+	return *r.Name
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetNodeID() string {
+	if r == nil || r.NodeID == nil {
+		return ""
+	}
+	return *r.NodeID
+}
+
+// GetPrerelease returns the Prerelease field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetPrerelease() bool {
+	if r == nil || r.Prerelease == nil {
+		return false
+	}
+	return *r.Prerelease
+}
+
+// GetPublishedAt returns the PublishedAt field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetPublishedAt() Timestamp {
+	if r == nil || r.PublishedAt == nil {
+		return Timestamp{}
+	}
+	return *r.PublishedAt
+}
+
+// GetTagName returns the TagName field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetTagName() string {
+	if r == nil || r.TagName == nil {
+		return ""
+	}
+	return *r.TagName
+}
+
+// GetTarballURL returns the TarballURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetTarballURL() string {
+	if r == nil || r.TarballURL == nil {
+		return ""
+	}
+	return *r.TarballURL
+}
+
+// GetTargetCommitish returns the TargetCommitish field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetTargetCommitish() string {
+	if r == nil || r.TargetCommitish == nil {
+		return ""
+	}
+	return *r.TargetCommitish
+}
+
+// GetUploadURL returns the UploadURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetUploadURL() string {
+	if r == nil || r.UploadURL == nil {
+		return ""
+	}
+	return *r.UploadURL
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetURL() string {
+	if r == nil || r.URL == nil {
+		return ""
+	}
+	return *r.URL
+}
+
+// GetZipballURL returns the ZipballURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetZipballURL() string {
+	if r == nil || r.ZipballURL == nil {
+		return ""
+	}
+	return *r.ZipballURL
+}
+
+// GetCommit returns the Commit field.
+func (r *RepositoryTag) GetCommit() *Commit {
+	if r == nil {
+		return nil
+	}
+	return r.Commit
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (r *RepositoryTag) GetName() string {
+	if r == nil || r.Name == nil {
+		return ""
+	}
+	return *r.Name
+}
+
+// GetTarballURL returns the TarballURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryTag) GetTarballURL() string {
+	if r == nil || r.TarballURL == nil {
+		return ""
+	}
+	return *r.TarballURL
+}
+
+// GetZipballURL returns the ZipballURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryTag) GetZipballURL() string {
+	if r == nil || r.ZipballURL == nil {
+		return ""
+	}
+	return *r.ZipballURL
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (r *RepositoryVulnerabilityAlertEvent) GetAction() string {
+	if r == nil || r.Action == nil {
+		return ""
+	}
+	return *r.Action
+}
+
+// GetForkRepos returns the ForkRepos field if it's non-nil, zero value otherwise.
+func (r *RepoStats) GetForkRepos() int {
+	if r == nil || r.ForkRepos == nil {
+		return 0
+	}
+	return *r.ForkRepos
+}
+
+// GetOrgRepos returns the OrgRepos field if it's non-nil, zero value otherwise.
+func (r *RepoStats) GetOrgRepos() int {
+	if r == nil || r.OrgRepos == nil {
+		return 0
+	}
+	return *r.OrgRepos
+}
+
+// GetRootRepos returns the RootRepos field if it's non-nil, zero value otherwise.
+func (r *RepoStats) GetRootRepos() int {
+	if r == nil || r.RootRepos == nil {
+		return 0
+	}
+	return *r.RootRepos
+}
+
+// GetTotalPushes returns the TotalPushes field if it's non-nil, zero value otherwise.
+func (r *RepoStats) GetTotalPushes() int {
+	if r == nil || r.TotalPushes == nil {
+		return 0
+	}
+	return *r.TotalPushes
+}
+
+// GetTotalRepos returns the TotalRepos field if it's non-nil, zero value otherwise.
+func (r *RepoStats) GetTotalRepos() int {
+	if r == nil || r.TotalRepos == nil {
+		return 0
+	}
+	return *r.TotalRepos
+}
+
+// GetTotalWikis returns the TotalWikis field if it's non-nil, zero value otherwise.
+func (r *RepoStats) GetTotalWikis() int {
+	if r == nil || r.TotalWikis == nil {
+		return 0
+	}
+	return *r.TotalWikis
+}
+
+// GetContext returns the Context field if it's non-nil, zero value otherwise.
+func (r *RepoStatus) GetContext() string {
+	if r == nil || r.Context == nil {
+		return ""
+	}
+	return *r.Context
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (r *RepoStatus) GetCreatedAt() time.Time {
+	if r == nil || r.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *r.CreatedAt
+}
+
+// GetCreator returns the Creator field.
+func (r *RepoStatus) GetCreator() *User {
+	if r == nil {
+		return nil
+	}
+	return r.Creator
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (r *RepoStatus) GetDescription() string {
+	if r == nil || r.Description == nil {
+		return ""
+	}
+	return *r.Description
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (r *RepoStatus) GetID() int64 {
+	if r == nil || r.ID == nil {
+		return 0
+	}
+	return *r.ID
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (r *RepoStatus) GetState() string {
+	if r == nil || r.State == nil {
+		return ""
+	}
+	return *r.State
+}
+
+// GetTargetURL returns the TargetURL field if it's non-nil, zero value otherwise.
+func (r *RepoStatus) GetTargetURL() string {
+	if r == nil || r.TargetURL == nil {
+		return ""
+	}
+	return *r.TargetURL
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (r *RepoStatus) GetUpdatedAt() time.Time {
+	if r == nil || r.UpdatedAt == nil {
+		return time.Time{}
+	}
+	return *r.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (r *RepoStatus) GetURL() string {
+	if r == nil || r.URL == nil {
+		return ""
+	}
+	return *r.URL
+}
+
+// GetStrict returns the Strict field if it's non-nil, zero value otherwise.
+func (r *RequiredStatusChecksRequest) GetStrict() bool {
+	if r == nil || r.Strict == nil {
+		return false
+	}
+	return *r.Strict
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (s *ServiceHook) GetName() string {
+	if s == nil || s.Name == nil {
+		return ""
+	}
+	return *s.Name
+}
+
+// GetEnabled returns the Enabled field if it's non-nil, zero value otherwise.
+func (s *SignaturesProtectedBranch) GetEnabled() bool {
+	if s == nil || s.Enabled == nil {
+		return false
+	}
+	return *s.Enabled
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (s *SignaturesProtectedBranch) GetURL() string {
+	if s == nil || s.URL == nil {
+		return ""
+	}
+	return *s.URL
+}
+
+// GetPayload returns the Payload field if it's non-nil, zero value otherwise.
+func (s *SignatureVerification) GetPayload() string {
+	if s == nil || s.Payload == nil {
+		return ""
+	}
+	return *s.Payload
+}
+
+// GetReason returns the Reason field if it's non-nil, zero value otherwise.
+func (s *SignatureVerification) GetReason() string {
+	if s == nil || s.Reason == nil {
+		return ""
+	}
+	return *s.Reason
+}
+
+// GetSignature returns the Signature field if it's non-nil, zero value otherwise.
+func (s *SignatureVerification) GetSignature() string {
+	if s == nil || s.Signature == nil {
+		return ""
+	}
+	return *s.Signature
+}
+
+// GetVerified returns the Verified field if it's non-nil, zero value otherwise.
+func (s *SignatureVerification) GetVerified() bool {
+	if s == nil || s.Verified == nil {
+		return false
+	}
+	return *s.Verified
+}
+
+// GetActor returns the Actor field.
+func (s *Source) GetActor() *User {
+	if s == nil {
+		return nil
+	}
+	return s.Actor
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (s *Source) GetID() int64 {
+	if s == nil || s.ID == nil {
+		return 0
+	}
+	return *s.ID
+}
+
+// GetIssue returns the Issue field.
+func (s *Source) GetIssue() *Issue {
+	if s == nil {
+		return nil
+	}
+	return s.Issue
+}
+
+// GetType returns the Type field if it's non-nil, zero value otherwise.
+func (s *Source) GetType() string {
+	if s == nil || s.Type == nil {
+		return ""
+	}
+	return *s.Type
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (s *Source) GetURL() string {
+	if s == nil || s.URL == nil {
+		return ""
+	}
+	return *s.URL
+}
+
+// GetEmail returns the Email field if it's non-nil, zero value otherwise.
+func (s *SourceImportAuthor) GetEmail() string {
+	if s == nil || s.Email == nil {
+		return ""
+	}
+	return *s.Email
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (s *SourceImportAuthor) GetID() int64 {
+	if s == nil || s.ID == nil {
+		return 0
+	}
+	return *s.ID
+}
+
+// GetImportURL returns the ImportURL field if it's non-nil, zero value otherwise.
+func (s *SourceImportAuthor) GetImportURL() string {
+	if s == nil || s.ImportURL == nil {
+		return ""
+	}
+	return *s.ImportURL
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (s *SourceImportAuthor) GetName() string {
+	if s == nil || s.Name == nil {
+		return ""
+	}
+	return *s.Name
+}
+
+// GetRemoteID returns the RemoteID field if it's non-nil, zero value otherwise.
+func (s *SourceImportAuthor) GetRemoteID() string {
+	if s == nil || s.RemoteID == nil {
+		return ""
+	}
+	return *s.RemoteID
+}
+
+// GetRemoteName returns the RemoteName field if it's non-nil, zero value otherwise.
+func (s *SourceImportAuthor) GetRemoteName() string {
+	if s == nil || s.RemoteName == nil {
+		return ""
+	}
+	return *s.RemoteName
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (s *SourceImportAuthor) GetURL() string {
+	if s == nil || s.URL == nil {
+		return ""
+	}
+	return *s.URL
+}
+
+// GetStarredAt returns the StarredAt field if it's non-nil, zero value otherwise.
+func (s *Stargazer) GetStarredAt() Timestamp {
+	if s == nil || s.StarredAt == nil {
+		return Timestamp{}
+	}
+	return *s.StarredAt
+}
+
+// GetUser returns the User field.
+func (s *Stargazer) GetUser() *User {
+	if s == nil {
+		return nil
+	}
+	return s.User
+}
+
+// GetRepository returns the Repository field.
+func (s *StarredRepository) GetRepository() *Repository {
+	if s == nil {
+		return nil
+	}
+	return s.Repository
+}
+
+// GetStarredAt returns the StarredAt field if it's non-nil, zero value otherwise.
+func (s *StarredRepository) GetStarredAt() Timestamp {
+	if s == nil || s.StarredAt == nil {
+		return Timestamp{}
+	}
+	return *s.StarredAt
+}
+
+// GetCommit returns the Commit field.
+func (s *StatusEvent) GetCommit() *RepositoryCommit {
+	if s == nil {
+		return nil
+	}
+	return s.Commit
+}
+
+// GetContext returns the Context field if it's non-nil, zero value otherwise.
+func (s *StatusEvent) GetContext() string {
+	if s == nil || s.Context == nil {
+		return ""
+	}
+	return *s.Context
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (s *StatusEvent) GetCreatedAt() Timestamp {
+	if s == nil || s.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *s.CreatedAt
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (s *StatusEvent) GetDescription() string {
+	if s == nil || s.Description == nil {
+		return ""
+	}
+	return *s.Description
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (s *StatusEvent) GetID() int64 {
+	if s == nil || s.ID == nil {
+		return 0
+	}
+	return *s.ID
+}
+
+// GetInstallation returns the Installation field.
+func (s *StatusEvent) GetInstallation() *Installation {
+	if s == nil {
+		return nil
+	}
+	return s.Installation
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (s *StatusEvent) GetName() string {
+	if s == nil || s.Name == nil {
+		return ""
+	}
+	return *s.Name
+}
+
+// GetRepo returns the Repo field.
+func (s *StatusEvent) GetRepo() *Repository {
+	if s == nil {
+		return nil
+	}
+	return s.Repo
+}
+
+// GetSender returns the Sender field.
+func (s *StatusEvent) GetSender() *User {
+	if s == nil {
+		return nil
+	}
+	return s.Sender
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (s *StatusEvent) GetSHA() string {
+	if s == nil || s.SHA == nil {
+		return ""
+	}
+	return *s.SHA
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (s *StatusEvent) GetState() string {
+	if s == nil || s.State == nil {
+		return ""
+	}
+	return *s.State
+}
+
+// GetTargetURL returns the TargetURL field if it's non-nil, zero value otherwise.
+func (s *StatusEvent) GetTargetURL() string {
+	if s == nil || s.TargetURL == nil {
+		return ""
+	}
+	return *s.TargetURL
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (s *StatusEvent) GetUpdatedAt() Timestamp {
+	if s == nil || s.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *s.UpdatedAt
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (s *Subscription) GetCreatedAt() Timestamp {
+	if s == nil || s.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *s.CreatedAt
+}
+
+// GetIgnored returns the Ignored field if it's non-nil, zero value otherwise.
+func (s *Subscription) GetIgnored() bool {
+	if s == nil || s.Ignored == nil {
+		return false
+	}
+	return *s.Ignored
+}
+
+// GetReason returns the Reason field if it's non-nil, zero value otherwise.
+func (s *Subscription) GetReason() string {
+	if s == nil || s.Reason == nil {
+		return ""
+	}
+	return *s.Reason
+}
+
+// GetRepositoryURL returns the RepositoryURL field if it's non-nil, zero value otherwise.
+func (s *Subscription) GetRepositoryURL() string {
+	if s == nil || s.RepositoryURL == nil {
+		return ""
+	}
+	return *s.RepositoryURL
+}
+
+// GetSubscribed returns the Subscribed field if it's non-nil, zero value otherwise.
+func (s *Subscription) GetSubscribed() bool {
+	if s == nil || s.Subscribed == nil {
+		return false
+	}
+	return *s.Subscribed
+}
+
+// GetThreadURL returns the ThreadURL field if it's non-nil, zero value otherwise.
+func (s *Subscription) GetThreadURL() string {
+	if s == nil || s.ThreadURL == nil {
+		return ""
+	}
+	return *s.ThreadURL
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (s *Subscription) GetURL() string {
+	if s == nil || s.URL == nil {
+		return ""
+	}
+	return *s.URL
+}
+
+// GetMessage returns the Message field if it's non-nil, zero value otherwise.
+func (t *Tag) GetMessage() string {
+	if t == nil || t.Message == nil {
+		return ""
+	}
+	return *t.Message
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (t *Tag) GetNodeID() string {
+	if t == nil || t.NodeID == nil {
+		return ""
+	}
+	return *t.NodeID
+}
+
+// GetObject returns the Object field.
+func (t *Tag) GetObject() *GitObject {
+	if t == nil {
+		return nil
+	}
+	return t.Object
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (t *Tag) GetSHA() string {
+	if t == nil || t.SHA == nil {
+		return ""
+	}
+	return *t.SHA
+}
+
+// GetTag returns the Tag field if it's non-nil, zero value otherwise.
+func (t *Tag) GetTag() string {
+	if t == nil || t.Tag == nil {
+		return ""
+	}
+	return *t.Tag
+}
+
+// GetTagger returns the Tagger field.
+func (t *Tag) GetTagger() *CommitAuthor {
+	if t == nil {
+		return nil
+	}
+	return t.Tagger
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (t *Tag) GetURL() string {
+	if t == nil || t.URL == nil {
+		return ""
+	}
+	return *t.URL
+}
+
+// GetVerification returns the Verification field.
+func (t *Tag) GetVerification() *SignatureVerification {
+	if t == nil {
+		return nil
+	}
+	return t.Verification
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (t *Team) GetDescription() string {
+	if t == nil || t.Description == nil {
+		return ""
+	}
+	return *t.Description
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (t *Team) GetID() int64 {
+	if t == nil || t.ID == nil {
+		return 0
+	}
+	return *t.ID
+}
+
+// GetLDAPDN returns the LDAPDN field if it's non-nil, zero value otherwise.
+func (t *Team) GetLDAPDN() string {
+	if t == nil || t.LDAPDN == nil {
+		return ""
+	}
+	return *t.LDAPDN
+}
+
+// GetMembersCount returns the MembersCount field if it's non-nil, zero value otherwise.
+func (t *Team) GetMembersCount() int {
+	if t == nil || t.MembersCount == nil {
+		return 0
+	}
+	return *t.MembersCount
+}
+
+// GetMembersURL returns the MembersURL field if it's non-nil, zero value otherwise.
+func (t *Team) GetMembersURL() string {
+	if t == nil || t.MembersURL == nil {
+		return ""
+	}
+	return *t.MembersURL
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (t *Team) GetName() string {
+	if t == nil || t.Name == nil {
+		return ""
+	}
+	return *t.Name
+}
+
+// GetOrganization returns the Organization field.
+func (t *Team) GetOrganization() *Organization {
+	if t == nil {
+		return nil
+	}
+	return t.Organization
+}
+
+// GetParent returns the Parent field.
+func (t *Team) GetParent() *Team {
+	if t == nil {
+		return nil
+	}
+	return t.Parent
+}
+
+// GetPermission returns the Permission field if it's non-nil, zero value otherwise.
+func (t *Team) GetPermission() string {
+	if t == nil || t.Permission == nil {
+		return ""
+	}
+	return *t.Permission
+}
+
+// GetPrivacy returns the Privacy field if it's non-nil, zero value otherwise.
+func (t *Team) GetPrivacy() string {
+	if t == nil || t.Privacy == nil {
+		return ""
+	}
+	return *t.Privacy
+}
+
+// GetReposCount returns the ReposCount field if it's non-nil, zero value otherwise.
+func (t *Team) GetReposCount() int {
+	if t == nil || t.ReposCount == nil {
+		return 0
+	}
+	return *t.ReposCount
+}
+
+// GetRepositoriesURL returns the RepositoriesURL field if it's non-nil, zero value otherwise.
+func (t *Team) GetRepositoriesURL() string {
+	if t == nil || t.RepositoriesURL == nil {
+		return ""
+	}
+	return *t.RepositoriesURL
+}
+
+// GetSlug returns the Slug field if it's non-nil, zero value otherwise.
+func (t *Team) GetSlug() string {
+	if t == nil || t.Slug == nil {
+		return ""
+	}
+	return *t.Slug
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (t *Team) GetURL() string {
+	if t == nil || t.URL == nil {
+		return ""
+	}
+	return *t.URL
+}
+
+// GetInstallation returns the Installation field.
+func (t *TeamAddEvent) GetInstallation() *Installation {
+	if t == nil {
+		return nil
+	}
+	return t.Installation
+}
+
+// GetOrg returns the Org field.
+func (t *TeamAddEvent) GetOrg() *Organization {
+	if t == nil {
+		return nil
+	}
+	return t.Org
+}
+
+// GetRepo returns the Repo field.
+func (t *TeamAddEvent) GetRepo() *Repository {
+	if t == nil {
+		return nil
+	}
+	return t.Repo
+}
+
+// GetSender returns the Sender field.
+func (t *TeamAddEvent) GetSender() *User {
+	if t == nil {
+		return nil
+	}
+	return t.Sender
+}
+
+// GetTeam returns the Team field.
+func (t *TeamAddEvent) GetTeam() *Team {
+	if t == nil {
+		return nil
+	}
+	return t.Team
+}
+
+// GetAuthor returns the Author field.
+func (t *TeamDiscussion) GetAuthor() *User {
+	if t == nil {
+		return nil
+	}
+	return t.Author
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (t *TeamDiscussion) GetBody() string {
+	if t == nil || t.Body == nil {
+		return ""
+	}
+	return *t.Body
+}
+
+// GetBodyHTML returns the BodyHTML field if it's non-nil, zero value otherwise.
+func (t *TeamDiscussion) GetBodyHTML() string {
+	if t == nil || t.BodyHTML == nil {
+		return ""
+	}
+	return *t.BodyHTML
+}
+
+// GetBodyVersion returns the BodyVersion field if it's non-nil, zero value otherwise.
+func (t *TeamDiscussion) GetBodyVersion() string {
+	if t == nil || t.BodyVersion == nil {
+		return ""
+	}
+	return *t.BodyVersion
+}
+
+// GetCommentsCount returns the CommentsCount field if it's non-nil, zero value otherwise.
+func (t *TeamDiscussion) GetCommentsCount() int {
+	if t == nil || t.CommentsCount == nil {
+		return 0
+	}
+	return *t.CommentsCount
+}
+
+// GetCommentsURL returns the CommentsURL field if it's non-nil, zero value otherwise.
+func (t *TeamDiscussion) GetCommentsURL() string {
+	if t == nil || t.CommentsURL == nil {
+		return ""
+	}
+	return *t.CommentsURL
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (t *TeamDiscussion) GetCreatedAt() Timestamp {
+	if t == nil || t.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *t.CreatedAt
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (t *TeamDiscussion) GetHTMLURL() string {
+	if t == nil || t.HTMLURL == nil {
+		return ""
+	}
+	return *t.HTMLURL
+}
+
+// GetLastEditedAt returns the LastEditedAt field if it's non-nil, zero value otherwise.
+func (t *TeamDiscussion) GetLastEditedAt() Timestamp {
+	if t == nil || t.LastEditedAt == nil {
+		return Timestamp{}
+	}
+	return *t.LastEditedAt
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (t *TeamDiscussion) GetNodeID() string {
+	if t == nil || t.NodeID == nil {
+		return ""
+	}
+	return *t.NodeID
+}
+
+// GetNumber returns the Number field if it's non-nil, zero value otherwise.
+func (t *TeamDiscussion) GetNumber() int {
+	if t == nil || t.Number == nil {
+		return 0
+	}
+	return *t.Number
+}
+
+// GetPinned returns the Pinned field if it's non-nil, zero value otherwise.
+func (t *TeamDiscussion) GetPinned() bool {
+	if t == nil || t.Pinned == nil {
+		return false
+	}
+	return *t.Pinned
+}
+
+// GetPrivate returns the Private field if it's non-nil, zero value otherwise.
+func (t *TeamDiscussion) GetPrivate() bool {
+	if t == nil || t.Private == nil {
+		return false
+	}
+	return *t.Private
+}
+
+// GetReactions returns the Reactions field.
+func (t *TeamDiscussion) GetReactions() *Reactions {
+	if t == nil {
+		return nil
+	}
+	return t.Reactions
+}
+
+// GetTeamURL returns the TeamURL field if it's non-nil, zero value otherwise.
+func (t *TeamDiscussion) GetTeamURL() string {
+	if t == nil || t.TeamURL == nil {
+		return ""
+	}
+	return *t.TeamURL
+}
+
+// GetTitle returns the Title field if it's non-nil, zero value otherwise.
+func (t *TeamDiscussion) GetTitle() string {
+	if t == nil || t.Title == nil {
+		return ""
+	}
+	return *t.Title
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (t *TeamDiscussion) GetUpdatedAt() Timestamp {
+	if t == nil || t.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *t.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (t *TeamDiscussion) GetURL() string {
+	if t == nil || t.URL == nil {
+		return ""
+	}
+	return *t.URL
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (t *TeamEvent) GetAction() string {
+	if t == nil || t.Action == nil {
+		return ""
+	}
+	return *t.Action
+}
+
+// GetChanges returns the Changes field.
+func (t *TeamEvent) GetChanges() *TeamChange {
+	if t == nil {
+		return nil
+	}
+	return t.Changes
+}
+
+// GetInstallation returns the Installation field.
+func (t *TeamEvent) GetInstallation() *Installation {
+	if t == nil {
+		return nil
+	}
+	return t.Installation
+}
+
+// GetOrg returns the Org field.
+func (t *TeamEvent) GetOrg() *Organization {
+	if t == nil {
+		return nil
+	}
+	return t.Org
+}
+
+// GetRepo returns the Repo field.
+func (t *TeamEvent) GetRepo() *Repository {
+	if t == nil {
+		return nil
+	}
+	return t.Repo
+}
+
+// GetSender returns the Sender field.
+func (t *TeamEvent) GetSender() *User {
+	if t == nil {
+		return nil
+	}
+	return t.Sender
+}
+
+// GetTeam returns the Team field.
+func (t *TeamEvent) GetTeam() *Team {
+	if t == nil {
+		return nil
+	}
+	return t.Team
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (t *TeamLDAPMapping) GetDescription() string {
+	if t == nil || t.Description == nil {
+		return ""
+	}
+	return *t.Description
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (t *TeamLDAPMapping) GetID() int64 {
+	if t == nil || t.ID == nil {
+		return 0
+	}
+	return *t.ID
+}
+
+// GetLDAPDN returns the LDAPDN field if it's non-nil, zero value otherwise.
+func (t *TeamLDAPMapping) GetLDAPDN() string {
+	if t == nil || t.LDAPDN == nil {
+		return ""
+	}
+	return *t.LDAPDN
+}
+
+// GetMembersURL returns the MembersURL field if it's non-nil, zero value otherwise.
+func (t *TeamLDAPMapping) GetMembersURL() string {
+	if t == nil || t.MembersURL == nil {
+		return ""
+	}
+	return *t.MembersURL
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (t *TeamLDAPMapping) GetName() string {
+	if t == nil || t.Name == nil {
+		return ""
+	}
+	return *t.Name
+}
+
+// GetPermission returns the Permission field if it's non-nil, zero value otherwise.
+func (t *TeamLDAPMapping) GetPermission() string {
+	if t == nil || t.Permission == nil {
+		return ""
+	}
+	return *t.Permission
+}
+
+// GetPrivacy returns the Privacy field if it's non-nil, zero value otherwise.
+func (t *TeamLDAPMapping) GetPrivacy() string {
+	if t == nil || t.Privacy == nil {
+		return ""
+	}
+	return *t.Privacy
+}
+
+// GetRepositoriesURL returns the RepositoriesURL field if it's non-nil, zero value otherwise.
+func (t *TeamLDAPMapping) GetRepositoriesURL() string {
+	if t == nil || t.RepositoriesURL == nil {
+		return ""
+	}
+	return *t.RepositoriesURL
+}
+
+// GetSlug returns the Slug field if it's non-nil, zero value otherwise.
+func (t *TeamLDAPMapping) GetSlug() string {
+	if t == nil || t.Slug == nil {
+		return ""
+	}
+	return *t.Slug
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (t *TeamLDAPMapping) GetURL() string {
+	if t == nil || t.URL == nil {
+		return ""
+	}
+	return *t.URL
+}
+
+// GetPermission returns the Permission field if it's non-nil, zero value otherwise.
+func (t *TeamProjectOptions) GetPermission() string {
+	if t == nil || t.Permission == nil {
+		return ""
+	}
+	return *t.Permission
+}
+
+// GetFragment returns the Fragment field if it's non-nil, zero value otherwise.
+func (t *TextMatch) GetFragment() string {
+	if t == nil || t.Fragment == nil {
+		return ""
+	}
+	return *t.Fragment
+}
+
+// GetObjectType returns the ObjectType field if it's non-nil, zero value otherwise.
+func (t *TextMatch) GetObjectType() string {
+	if t == nil || t.ObjectType == nil {
+		return ""
+	}
+	return *t.ObjectType
+}
+
+// GetObjectURL returns the ObjectURL field if it's non-nil, zero value otherwise.
+func (t *TextMatch) GetObjectURL() string {
+	if t == nil || t.ObjectURL == nil {
+		return ""
+	}
+	return *t.ObjectURL
+}
+
+// GetProperty returns the Property field if it's non-nil, zero value otherwise.
+func (t *TextMatch) GetProperty() string {
+	if t == nil || t.Property == nil {
+		return ""
+	}
+	return *t.Property
+}
+
+// GetActor returns the Actor field.
+func (t *Timeline) GetActor() *User {
+	if t == nil {
+		return nil
+	}
+	return t.Actor
+}
+
+// GetAssignee returns the Assignee field.
+func (t *Timeline) GetAssignee() *User {
+	if t == nil {
+		return nil
+	}
+	return t.Assignee
+}
+
+// GetCommitID returns the CommitID field if it's non-nil, zero value otherwise.
+func (t *Timeline) GetCommitID() string {
+	if t == nil || t.CommitID == nil {
+		return ""
+	}
+	return *t.CommitID
+}
+
+// GetCommitURL returns the CommitURL field if it's non-nil, zero value otherwise.
+func (t *Timeline) GetCommitURL() string {
+	if t == nil || t.CommitURL == nil {
+		return ""
+	}
+	return *t.CommitURL
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (t *Timeline) GetCreatedAt() time.Time {
+	if t == nil || t.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *t.CreatedAt
+}
+
+// GetEvent returns the Event field if it's non-nil, zero value otherwise.
+func (t *Timeline) GetEvent() string {
+	if t == nil || t.Event == nil {
+		return ""
+	}
+	return *t.Event
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (t *Timeline) GetID() int64 {
+	if t == nil || t.ID == nil {
+		return 0
+	}
+	return *t.ID
+}
+
+// GetLabel returns the Label field.
+func (t *Timeline) GetLabel() *Label {
+	if t == nil {
+		return nil
+	}
+	return t.Label
+}
+
+// GetMilestone returns the Milestone field.
+func (t *Timeline) GetMilestone() *Milestone {
+	if t == nil {
+		return nil
+	}
+	return t.Milestone
+}
+
+// GetProjectCard returns the ProjectCard field.
+func (t *Timeline) GetProjectCard() *ProjectCard {
+	if t == nil {
+		return nil
+	}
+	return t.ProjectCard
+}
+
+// GetRename returns the Rename field.
+func (t *Timeline) GetRename() *Rename {
+	if t == nil {
+		return nil
+	}
+	return t.Rename
+}
+
+// GetSource returns the Source field.
+func (t *Timeline) GetSource() *Source {
+	if t == nil {
+		return nil
+	}
+	return t.Source
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (t *Timeline) GetURL() string {
+	if t == nil || t.URL == nil {
+		return ""
+	}
+	return *t.URL
+}
+
+// GetCount returns the Count field if it's non-nil, zero value otherwise.
+func (t *TrafficClones) GetCount() int {
+	if t == nil || t.Count == nil {
+		return 0
+	}
+	return *t.Count
+}
+
+// GetUniques returns the Uniques field if it's non-nil, zero value otherwise.
+func (t *TrafficClones) GetUniques() int {
+	if t == nil || t.Uniques == nil {
+		return 0
+	}
+	return *t.Uniques
+}
+
+// GetCount returns the Count field if it's non-nil, zero value otherwise.
+func (t *TrafficData) GetCount() int {
+	if t == nil || t.Count == nil {
+		return 0
+	}
+	return *t.Count
+}
+
+// GetTimestamp returns the Timestamp field if it's non-nil, zero value otherwise.
+func (t *TrafficData) GetTimestamp() Timestamp {
+	if t == nil || t.Timestamp == nil {
+		return Timestamp{}
+	}
+	return *t.Timestamp
+}
+
+// GetUniques returns the Uniques field if it's non-nil, zero value otherwise.
+func (t *TrafficData) GetUniques() int {
+	if t == nil || t.Uniques == nil {
+		return 0
+	}
+	return *t.Uniques
+}
+
+// GetCount returns the Count field if it's non-nil, zero value otherwise.
+func (t *TrafficPath) GetCount() int {
+	if t == nil || t.Count == nil {
+		return 0
+	}
+	return *t.Count
+}
+
+// GetPath returns the Path field if it's non-nil, zero value otherwise.
+func (t *TrafficPath) GetPath() string {
+	if t == nil || t.Path == nil {
+		return ""
+	}
+	return *t.Path
+}
+
+// GetTitle returns the Title field if it's non-nil, zero value otherwise.
+func (t *TrafficPath) GetTitle() string {
+	if t == nil || t.Title == nil {
+		return ""
+	}
+	return *t.Title
+}
+
+// GetUniques returns the Uniques field if it's non-nil, zero value otherwise.
+func (t *TrafficPath) GetUniques() int {
+	if t == nil || t.Uniques == nil {
+		return 0
+	}
+	return *t.Uniques
+}
+
+// GetCount returns the Count field if it's non-nil, zero value otherwise.
+func (t *TrafficReferrer) GetCount() int {
+	if t == nil || t.Count == nil {
+		return 0
+	}
+	return *t.Count
+}
+
+// GetReferrer returns the Referrer field if it's non-nil, zero value otherwise.
+func (t *TrafficReferrer) GetReferrer() string {
+	if t == nil || t.Referrer == nil {
+		return ""
+	}
+	return *t.Referrer
+}
+
+// GetUniques returns the Uniques field if it's non-nil, zero value otherwise.
+func (t *TrafficReferrer) GetUniques() int {
+	if t == nil || t.Uniques == nil {
+		return 0
+	}
+	return *t.Uniques
+}
+
+// GetCount returns the Count field if it's non-nil, zero value otherwise.
+func (t *TrafficViews) GetCount() int {
+	if t == nil || t.Count == nil {
+		return 0
+	}
+	return *t.Count
+}
+
+// GetUniques returns the Uniques field if it's non-nil, zero value otherwise.
+func (t *TrafficViews) GetUniques() int {
+	if t == nil || t.Uniques == nil {
+		return 0
+	}
+	return *t.Uniques
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (t *Tree) GetSHA() string {
+	if t == nil || t.SHA == nil {
+		return ""
+	}
+	return *t.SHA
+}
+
+// GetTruncated returns the Truncated field if it's non-nil, zero value otherwise.
+func (t *Tree) GetTruncated() bool {
+	if t == nil || t.Truncated == nil {
+		return false
+	}
+	return *t.Truncated
+}
+
+// GetContent returns the Content field if it's non-nil, zero value otherwise.
+func (t *TreeEntry) GetContent() string {
+	if t == nil || t.Content == nil {
+		return ""
+	}
+	return *t.Content
+}
+
+// GetMode returns the Mode field if it's non-nil, zero value otherwise.
+func (t *TreeEntry) GetMode() string {
+	if t == nil || t.Mode == nil {
+		return ""
+	}
+	return *t.Mode
+}
+
+// GetPath returns the Path field if it's non-nil, zero value otherwise.
+func (t *TreeEntry) GetPath() string {
+	if t == nil || t.Path == nil {
+		return ""
+	}
+	return *t.Path
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (t *TreeEntry) GetSHA() string {
+	if t == nil || t.SHA == nil {
+		return ""
+	}
+	return *t.SHA
+}
+
+// GetSize returns the Size field if it's non-nil, zero value otherwise.
+func (t *TreeEntry) GetSize() int {
+	if t == nil || t.Size == nil {
+		return 0
+	}
+	return *t.Size
+}
+
+// GetType returns the Type field if it's non-nil, zero value otherwise.
+func (t *TreeEntry) GetType() string {
+	if t == nil || t.Type == nil {
+		return ""
+	}
+	return *t.Type
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (t *TreeEntry) GetURL() string {
+	if t == nil || t.URL == nil {
+		return ""
+	}
+	return *t.URL
+}
+
+// GetCompletedAt returns the CompletedAt field if it's non-nil, zero value otherwise.
+func (u *UpdateCheckRunOptions) GetCompletedAt() Timestamp {
+	if u == nil || u.CompletedAt == nil {
+		return Timestamp{}
+	}
+	return *u.CompletedAt
+}
+
+// GetConclusion returns the Conclusion field if it's non-nil, zero value otherwise.
+func (u *UpdateCheckRunOptions) GetConclusion() string {
+	if u == nil || u.Conclusion == nil {
+		return ""
+	}
+	return *u.Conclusion
+}
+
+// GetDetailsURL returns the DetailsURL field if it's non-nil, zero value otherwise.
+func (u *UpdateCheckRunOptions) GetDetailsURL() string {
+	if u == nil || u.DetailsURL == nil {
+		return ""
+	}
+	return *u.DetailsURL
+}
+
+// GetExternalID returns the ExternalID field if it's non-nil, zero value otherwise.
+func (u *UpdateCheckRunOptions) GetExternalID() string {
+	if u == nil || u.ExternalID == nil {
+		return ""
+	}
+	return *u.ExternalID
+}
+
+// GetHeadBranch returns the HeadBranch field if it's non-nil, zero value otherwise.
+func (u *UpdateCheckRunOptions) GetHeadBranch() string {
+	if u == nil || u.HeadBranch == nil {
+		return ""
+	}
+	return *u.HeadBranch
+}
+
+// GetHeadSHA returns the HeadSHA field if it's non-nil, zero value otherwise.
+func (u *UpdateCheckRunOptions) GetHeadSHA() string {
+	if u == nil || u.HeadSHA == nil {
+		return ""
+	}
+	return *u.HeadSHA
+}
+
+// GetOutput returns the Output field.
+func (u *UpdateCheckRunOptions) GetOutput() *CheckRunOutput {
+	if u == nil {
+		return nil
+	}
+	return u.Output
+}
+
+// GetStatus returns the Status field if it's non-nil, zero value otherwise.
+func (u *UpdateCheckRunOptions) GetStatus() string {
+	if u == nil || u.Status == nil {
+		return ""
+	}
+	return *u.Status
+}
+
+// GetAvatarURL returns the AvatarURL field if it's non-nil, zero value otherwise.
+func (u *User) GetAvatarURL() string {
+	if u == nil || u.AvatarURL == nil {
+		return ""
+	}
+	return *u.AvatarURL
+}
+
+// GetBio returns the Bio field if it's non-nil, zero value otherwise.
+func (u *User) GetBio() string {
+	if u == nil || u.Bio == nil {
+		return ""
+	}
+	return *u.Bio
+}
+
+// GetBlog returns the Blog field if it's non-nil, zero value otherwise.
+func (u *User) GetBlog() string {
+	if u == nil || u.Blog == nil {
+		return ""
+	}
+	return *u.Blog
+}
+
+// GetCollaborators returns the Collaborators field if it's non-nil, zero value otherwise.
+func (u *User) GetCollaborators() int {
+	if u == nil || u.Collaborators == nil {
+		return 0
+	}
+	return *u.Collaborators
+}
+
+// GetCompany returns the Company field if it's non-nil, zero value otherwise.
+func (u *User) GetCompany() string {
+	if u == nil || u.Company == nil {
+		return ""
+	}
+	return *u.Company
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (u *User) GetCreatedAt() Timestamp {
+	if u == nil || u.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *u.CreatedAt
+}
+
+// GetDiskUsage returns the DiskUsage field if it's non-nil, zero value otherwise.
+func (u *User) GetDiskUsage() int {
+	if u == nil || u.DiskUsage == nil {
+		return 0
+	}
+	return *u.DiskUsage
+}
+
+// GetEmail returns the Email field if it's non-nil, zero value otherwise.
+func (u *User) GetEmail() string {
+	if u == nil || u.Email == nil {
+		return ""
+	}
+	return *u.Email
+}
+
+// GetEventsURL returns the EventsURL field if it's non-nil, zero value otherwise.
+func (u *User) GetEventsURL() string {
+	if u == nil || u.EventsURL == nil {
+		return ""
+	}
+	return *u.EventsURL
+}
+
+// GetFollowers returns the Followers field if it's non-nil, zero value otherwise.
+func (u *User) GetFollowers() int {
+	if u == nil || u.Followers == nil {
+		return 0
+	}
+	return *u.Followers
+}
+
+// GetFollowersURL returns the FollowersURL field if it's non-nil, zero value otherwise.
+func (u *User) GetFollowersURL() string {
+	if u == nil || u.FollowersURL == nil {
+		return ""
+	}
+	return *u.FollowersURL
+}
+
+// GetFollowing returns the Following field if it's non-nil, zero value otherwise.
+func (u *User) GetFollowing() int {
+	if u == nil || u.Following == nil {
+		return 0
+	}
+	return *u.Following
+}
+
+// GetFollowingURL returns the FollowingURL field if it's non-nil, zero value otherwise.
+func (u *User) GetFollowingURL() string {
+	if u == nil || u.FollowingURL == nil {
+		return ""
+	}
+	return *u.FollowingURL
+}
+
+// GetGistsURL returns the GistsURL field if it's non-nil, zero value otherwise.
+func (u *User) GetGistsURL() string {
+	if u == nil || u.GistsURL == nil {
+		return ""
+	}
+	return *u.GistsURL
+}
+
+// GetGravatarID returns the GravatarID field if it's non-nil, zero value otherwise.
+func (u *User) GetGravatarID() string {
+	if u == nil || u.GravatarID == nil {
+		return ""
+	}
+	return *u.GravatarID
+}
+
+// GetHireable returns the Hireable field if it's non-nil, zero value otherwise.
+func (u *User) GetHireable() bool {
+	if u == nil || u.Hireable == nil {
+		return false
+	}
+	return *u.Hireable
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (u *User) GetHTMLURL() string {
+	if u == nil || u.HTMLURL == nil {
+		return ""
+	}
+	return *u.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (u *User) GetID() int64 {
+	if u == nil || u.ID == nil {
+		return 0
+	}
+	return *u.ID
+}
+
+// GetLocation returns the Location field if it's non-nil, zero value otherwise.
+func (u *User) GetLocation() string {
+	if u == nil || u.Location == nil {
+		return ""
+	}
+	return *u.Location
+}
+
+// GetLogin returns the Login field if it's non-nil, zero value otherwise.
+func (u *User) GetLogin() string {
+	if u == nil || u.Login == nil {
+		return ""
+	}
+	return *u.Login
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (u *User) GetName() string {
+	if u == nil || u.Name == nil {
+		return ""
+	}
+	return *u.Name
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (u *User) GetNodeID() string {
+	if u == nil || u.NodeID == nil {
+		return ""
+	}
+	return *u.NodeID
+}
+
+// GetOrganizationsURL returns the OrganizationsURL field if it's non-nil, zero value otherwise.
+func (u *User) GetOrganizationsURL() string {
+	if u == nil || u.OrganizationsURL == nil {
+		return ""
+	}
+	return *u.OrganizationsURL
+}
+
+// GetOwnedPrivateRepos returns the OwnedPrivateRepos field if it's non-nil, zero value otherwise.
+func (u *User) GetOwnedPrivateRepos() int {
+	if u == nil || u.OwnedPrivateRepos == nil {
+		return 0
+	}
+	return *u.OwnedPrivateRepos
+}
+
+// GetPermissions returns the Permissions field if it's non-nil, zero value otherwise.
+func (u *User) GetPermissions() map[string]bool {
+	if u == nil || u.Permissions == nil {
+		return map[string]bool{}
+	}
+	return *u.Permissions
+}
+
+// GetPlan returns the Plan field.
+func (u *User) GetPlan() *Plan {
+	if u == nil {
+		return nil
+	}
+	return u.Plan
+}
+
+// GetPrivateGists returns the PrivateGists field if it's non-nil, zero value otherwise.
+func (u *User) GetPrivateGists() int {
+	if u == nil || u.PrivateGists == nil {
+		return 0
+	}
+	return *u.PrivateGists
+}
+
+// GetPublicGists returns the PublicGists field if it's non-nil, zero value otherwise.
+func (u *User) GetPublicGists() int {
+	if u == nil || u.PublicGists == nil {
+		return 0
+	}
+	return *u.PublicGists
+}
+
+// GetPublicRepos returns the PublicRepos field if it's non-nil, zero value otherwise.
+func (u *User) GetPublicRepos() int {
+	if u == nil || u.PublicRepos == nil {
+		return 0
+	}
+	return *u.PublicRepos
+}
+
+// GetReceivedEventsURL returns the ReceivedEventsURL field if it's non-nil, zero value otherwise.
+func (u *User) GetReceivedEventsURL() string {
+	if u == nil || u.ReceivedEventsURL == nil {
+		return ""
+	}
+	return *u.ReceivedEventsURL
+}
+
+// GetReposURL returns the ReposURL field if it's non-nil, zero value otherwise.
+func (u *User) GetReposURL() string {
+	if u == nil || u.ReposURL == nil {
+		return ""
+	}
+	return *u.ReposURL
+}
+
+// GetSiteAdmin returns the SiteAdmin field if it's non-nil, zero value otherwise.
+func (u *User) GetSiteAdmin() bool {
+	if u == nil || u.SiteAdmin == nil {
+		return false
+	}
+	return *u.SiteAdmin
+}
+
+// GetStarredURL returns the StarredURL field if it's non-nil, zero value otherwise.
+func (u *User) GetStarredURL() string {
+	if u == nil || u.StarredURL == nil {
+		return ""
+	}
+	return *u.StarredURL
+}
+
+// GetSubscriptionsURL returns the SubscriptionsURL field if it's non-nil, zero value otherwise.
+func (u *User) GetSubscriptionsURL() string {
+	if u == nil || u.SubscriptionsURL == nil {
+		return ""
+	}
+	return *u.SubscriptionsURL
+}
+
+// GetSuspendedAt returns the SuspendedAt field if it's non-nil, zero value otherwise.
+func (u *User) GetSuspendedAt() Timestamp {
+	if u == nil || u.SuspendedAt == nil {
+		return Timestamp{}
+	}
+	return *u.SuspendedAt
+}
+
+// GetTotalPrivateRepos returns the TotalPrivateRepos field if it's non-nil, zero value otherwise.
+func (u *User) GetTotalPrivateRepos() int {
+	if u == nil || u.TotalPrivateRepos == nil {
+		return 0
+	}
+	return *u.TotalPrivateRepos
+}
+
+// GetTwoFactorAuthentication returns the TwoFactorAuthentication field if it's non-nil, zero value otherwise.
+func (u *User) GetTwoFactorAuthentication() bool {
+	if u == nil || u.TwoFactorAuthentication == nil {
+		return false
+	}
+	return *u.TwoFactorAuthentication
+}
+
+// GetType returns the Type field if it's non-nil, zero value otherwise.
+func (u *User) GetType() string {
+	if u == nil || u.Type == nil {
+		return ""
+	}
+	return *u.Type
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (u *User) GetUpdatedAt() Timestamp {
+	if u == nil || u.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *u.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (u *User) GetURL() string {
+	if u == nil || u.URL == nil {
+		return ""
+	}
+	return *u.URL
+}
+
+// GetMessage returns the Message field if it's non-nil, zero value otherwise.
+func (u *UserContext) GetMessage() string {
+	if u == nil || u.Message == nil {
+		return ""
+	}
+	return *u.Message
+}
+
+// GetOcticon returns the Octicon field if it's non-nil, zero value otherwise.
+func (u *UserContext) GetOcticon() string {
+	if u == nil || u.Octicon == nil {
+		return ""
+	}
+	return *u.Octicon
+}
+
+// GetEmail returns the Email field if it's non-nil, zero value otherwise.
+func (u *UserEmail) GetEmail() string {
+	if u == nil || u.Email == nil {
+		return ""
+	}
+	return *u.Email
+}
+
+// GetPrimary returns the Primary field if it's non-nil, zero value otherwise.
+func (u *UserEmail) GetPrimary() bool {
+	if u == nil || u.Primary == nil {
+		return false
+	}
+	return *u.Primary
+}
+
+// GetVerified returns the Verified field if it's non-nil, zero value otherwise.
+func (u *UserEmail) GetVerified() bool {
+	if u == nil || u.Verified == nil {
+		return false
+	}
+	return *u.Verified
+}
+
+// GetAvatarURL returns the AvatarURL field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetAvatarURL() string {
+	if u == nil || u.AvatarURL == nil {
+		return ""
+	}
+	return *u.AvatarURL
+}
+
+// GetEventsURL returns the EventsURL field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetEventsURL() string {
+	if u == nil || u.EventsURL == nil {
+		return ""
+	}
+	return *u.EventsURL
+}
+
+// GetFollowersURL returns the FollowersURL field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetFollowersURL() string {
+	if u == nil || u.FollowersURL == nil {
+		return ""
+	}
+	return *u.FollowersURL
+}
+
+// GetFollowingURL returns the FollowingURL field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetFollowingURL() string {
+	if u == nil || u.FollowingURL == nil {
+		return ""
+	}
+	return *u.FollowingURL
+}
+
+// GetGistsURL returns the GistsURL field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetGistsURL() string {
+	if u == nil || u.GistsURL == nil {
+		return ""
+	}
+	return *u.GistsURL
+}
+
+// GetGravatarID returns the GravatarID field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetGravatarID() string {
+	if u == nil || u.GravatarID == nil {
+		return ""
+	}
+	return *u.GravatarID
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetID() int64 {
+	if u == nil || u.ID == nil {
+		return 0
+	}
+	return *u.ID
+}
+
+// GetLDAPDN returns the LDAPDN field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetLDAPDN() string {
+	if u == nil || u.LDAPDN == nil {
+		return ""
+	}
+	return *u.LDAPDN
+}
+
+// GetLogin returns the Login field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetLogin() string {
+	if u == nil || u.Login == nil {
+		return ""
+	}
+	return *u.Login
+}
+
+// GetOrganizationsURL returns the OrganizationsURL field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetOrganizationsURL() string {
+	if u == nil || u.OrganizationsURL == nil {
+		return ""
+	}
+	return *u.OrganizationsURL
+}
+
+// GetReceivedEventsURL returns the ReceivedEventsURL field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetReceivedEventsURL() string {
+	if u == nil || u.ReceivedEventsURL == nil {
+		return ""
+	}
+	return *u.ReceivedEventsURL
+}
+
+// GetReposURL returns the ReposURL field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetReposURL() string {
+	if u == nil || u.ReposURL == nil {
+		return ""
+	}
+	return *u.ReposURL
+}
+
+// GetSiteAdmin returns the SiteAdmin field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetSiteAdmin() bool {
+	if u == nil || u.SiteAdmin == nil {
+		return false
+	}
+	return *u.SiteAdmin
+}
+
+// GetStarredURL returns the StarredURL field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetStarredURL() string {
+	if u == nil || u.StarredURL == nil {
+		return ""
+	}
+	return *u.StarredURL
+}
+
+// GetSubscriptionsURL returns the SubscriptionsURL field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetSubscriptionsURL() string {
+	if u == nil || u.SubscriptionsURL == nil {
+		return ""
+	}
+	return *u.SubscriptionsURL
+}
+
+// GetType returns the Type field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetType() string {
+	if u == nil || u.Type == nil {
+		return ""
+	}
+	return *u.Type
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetURL() string {
+	if u == nil || u.URL == nil {
+		return ""
+	}
+	return *u.URL
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (u *UserMigration) GetCreatedAt() string {
+	if u == nil || u.CreatedAt == nil {
+		return ""
+	}
+	return *u.CreatedAt
+}
+
+// GetExcludeAttachments returns the ExcludeAttachments field if it's non-nil, zero value otherwise.
+func (u *UserMigration) GetExcludeAttachments() bool {
+	if u == nil || u.ExcludeAttachments == nil {
+		return false
+	}
+	return *u.ExcludeAttachments
+}
+
+// GetGUID returns the GUID field if it's non-nil, zero value otherwise.
+func (u *UserMigration) GetGUID() string {
+	if u == nil || u.GUID == nil {
+		return ""
+	}
+	return *u.GUID
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (u *UserMigration) GetID() int64 {
+	if u == nil || u.ID == nil {
+		return 0
+	}
+	return *u.ID
+}
+
+// GetLockRepositories returns the LockRepositories field if it's non-nil, zero value otherwise.
+func (u *UserMigration) GetLockRepositories() bool {
+	if u == nil || u.LockRepositories == nil {
+		return false
+	}
+	return *u.LockRepositories
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (u *UserMigration) GetState() string {
+	if u == nil || u.State == nil {
+		return ""
+	}
+	return *u.State
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (u *UserMigration) GetUpdatedAt() string {
+	if u == nil || u.UpdatedAt == nil {
+		return ""
+	}
+	return *u.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (u *UserMigration) GetURL() string {
+	if u == nil || u.URL == nil {
+		return ""
+	}
+	return *u.URL
+}
+
+// GetIncompleteResults returns the IncompleteResults field if it's non-nil, zero value otherwise.
+func (u *UsersSearchResult) GetIncompleteResults() bool {
+	if u == nil || u.IncompleteResults == nil {
+		return false
+	}
+	return *u.IncompleteResults
+}
+
+// GetTotal returns the Total field if it's non-nil, zero value otherwise.
+func (u *UsersSearchResult) GetTotal() int {
+	if u == nil || u.Total == nil {
+		return 0
+	}
+	return *u.Total
+}
+
+// GetAdminUsers returns the AdminUsers field if it's non-nil, zero value otherwise.
+func (u *UserStats) GetAdminUsers() int {
+	if u == nil || u.AdminUsers == nil {
+		return 0
+	}
+	return *u.AdminUsers
+}
+
+// GetSuspendedUsers returns the SuspendedUsers field if it's non-nil, zero value otherwise.
+func (u *UserStats) GetSuspendedUsers() int {
+	if u == nil || u.SuspendedUsers == nil {
+		return 0
+	}
+	return *u.SuspendedUsers
+}
+
+// GetTotalUsers returns the TotalUsers field if it's non-nil, zero value otherwise.
+func (u *UserStats) GetTotalUsers() int {
+	if u == nil || u.TotalUsers == nil {
+		return 0
+	}
+	return *u.TotalUsers
+}
+
+// GetReason returns the Reason field if it's non-nil, zero value otherwise.
+func (u *UserSuspendOptions) GetReason() string {
+	if u == nil || u.Reason == nil {
+		return ""
+	}
+	return *u.Reason
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (w *WatchEvent) GetAction() string {
+	if w == nil || w.Action == nil {
+		return ""
+	}
+	return *w.Action
+}
+
+// GetInstallation returns the Installation field.
+func (w *WatchEvent) GetInstallation() *Installation {
+	if w == nil {
+		return nil
+	}
+	return w.Installation
+}
+
+// GetRepo returns the Repo field.
+func (w *WatchEvent) GetRepo() *Repository {
+	if w == nil {
+		return nil
+	}
+	return w.Repo
+}
+
+// GetSender returns the Sender field.
+func (w *WatchEvent) GetSender() *User {
+	if w == nil {
+		return nil
+	}
+	return w.Sender
+}
+
+// GetEmail returns the Email field if it's non-nil, zero value otherwise.
+func (w *WebHookAuthor) GetEmail() string {
+	if w == nil || w.Email == nil {
+		return ""
+	}
+	return *w.Email
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (w *WebHookAuthor) GetName() string {
+	if w == nil || w.Name == nil {
+		return ""
+	}
+	return *w.Name
+}
+
+// GetUsername returns the Username field if it's non-nil, zero value otherwise.
+func (w *WebHookAuthor) GetUsername() string {
+	if w == nil || w.Username == nil {
+		return ""
+	}
+	return *w.Username
+}
+
+// GetAuthor returns the Author field.
+func (w *WebHookCommit) GetAuthor() *WebHookAuthor {
+	if w == nil {
+		return nil
+	}
+	return w.Author
+}
+
+// GetCommitter returns the Committer field.
+func (w *WebHookCommit) GetCommitter() *WebHookAuthor {
+	if w == nil {
+		return nil
+	}
+	return w.Committer
+}
+
+// GetDistinct returns the Distinct field if it's non-nil, zero value otherwise.
+func (w *WebHookCommit) GetDistinct() bool {
+	if w == nil || w.Distinct == nil {
+		return false
+	}
+	return *w.Distinct
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (w *WebHookCommit) GetID() string {
+	if w == nil || w.ID == nil {
+		return ""
+	}
+	return *w.ID
+}
+
+// GetMessage returns the Message field if it's non-nil, zero value otherwise.
+func (w *WebHookCommit) GetMessage() string {
+	if w == nil || w.Message == nil {
+		return ""
+	}
+	return *w.Message
+}
+
+// GetTimestamp returns the Timestamp field if it's non-nil, zero value otherwise.
+func (w *WebHookCommit) GetTimestamp() time.Time {
+	if w == nil || w.Timestamp == nil {
+		return time.Time{}
+	}
+	return *w.Timestamp
+}
+
+// GetAfter returns the After field if it's non-nil, zero value otherwise.
+func (w *WebHookPayload) GetAfter() string {
+	if w == nil || w.After == nil {
+		return ""
+	}
+	return *w.After
+}
+
+// GetBefore returns the Before field if it's non-nil, zero value otherwise.
+func (w *WebHookPayload) GetBefore() string {
+	if w == nil || w.Before == nil {
+		return ""
+	}
+	return *w.Before
+}
+
+// GetCompare returns the Compare field if it's non-nil, zero value otherwise.
+func (w *WebHookPayload) GetCompare() string {
+	if w == nil || w.Compare == nil {
+		return ""
+	}
+	return *w.Compare
+}
+
+// GetCreated returns the Created field if it's non-nil, zero value otherwise.
+func (w *WebHookPayload) GetCreated() bool {
+	if w == nil || w.Created == nil {
+		return false
+	}
+	return *w.Created
+}
+
+// GetDeleted returns the Deleted field if it's non-nil, zero value otherwise.
+func (w *WebHookPayload) GetDeleted() bool {
+	if w == nil || w.Deleted == nil {
+		return false
+	}
+	return *w.Deleted
+}
+
+// GetForced returns the Forced field if it's non-nil, zero value otherwise.
+func (w *WebHookPayload) GetForced() bool {
+	if w == nil || w.Forced == nil {
+		return false
+	}
+	return *w.Forced
+}
+
+// GetHeadCommit returns the HeadCommit field.
+func (w *WebHookPayload) GetHeadCommit() *WebHookCommit {
+	if w == nil {
+		return nil
+	}
+	return w.HeadCommit
+}
+
+// GetPusher returns the Pusher field.
+func (w *WebHookPayload) GetPusher() *User {
+	if w == nil {
+		return nil
+	}
+	return w.Pusher
+}
+
+// GetRef returns the Ref field if it's non-nil, zero value otherwise.
+func (w *WebHookPayload) GetRef() string {
+	if w == nil || w.Ref == nil {
+		return ""
+	}
+	return *w.Ref
+}
+
+// GetRepo returns the Repo field.
+func (w *WebHookPayload) GetRepo() *Repository {
+	if w == nil {
+		return nil
+	}
+	return w.Repo
+}
+
+// GetSender returns the Sender field.
+func (w *WebHookPayload) GetSender() *User {
+	if w == nil {
+		return nil
+	}
+	return w.Sender
+}
+
+// GetTotal returns the Total field if it's non-nil, zero value otherwise.
+func (w *WeeklyCommitActivity) GetTotal() int {
+	if w == nil || w.Total == nil {
+		return 0
+	}
+	return *w.Total
+}
+
+// GetWeek returns the Week field if it's non-nil, zero value otherwise.
+func (w *WeeklyCommitActivity) GetWeek() Timestamp {
+	if w == nil || w.Week == nil {
+		return Timestamp{}
+	}
+	return *w.Week
+}
+
+// GetAdditions returns the Additions field if it's non-nil, zero value otherwise.
+func (w *WeeklyStats) GetAdditions() int {
+	if w == nil || w.Additions == nil {
+		return 0
+	}
+	return *w.Additions
+}
+
+// GetCommits returns the Commits field if it's non-nil, zero value otherwise.
+func (w *WeeklyStats) GetCommits() int {
+	if w == nil || w.Commits == nil {
+		return 0
+	}
+	return *w.Commits
+}
+
+// GetDeletions returns the Deletions field if it's non-nil, zero value otherwise.
+func (w *WeeklyStats) GetDeletions() int {
+	if w == nil || w.Deletions == nil {
+		return 0
+	}
+	return *w.Deletions
+}
+
+// GetWeek returns the Week field if it's non-nil, zero value otherwise.
+func (w *WeeklyStats) GetWeek() Timestamp {
+	if w == nil || w.Week == nil {
+		return Timestamp{}
+	}
+	return *w.Week
+}
diff --git a/vendor/github.com/google/go-github/v24/github/github.go b/vendor/github.com/google/go-github/v24/github/github.go
new file mode 100644
index 000000000..4d86d76b7
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/github.go
@@ -0,0 +1,1022 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:generate go run gen-accessors.go
+
+package github
+
+import (
+	"bytes"
+	"context"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+	"reflect"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/google/go-querystring/query"
+)
+
+const (
+	defaultBaseURL = "https://api.github.com/"
+	uploadBaseURL  = "https://uploads.github.com/"
+	userAgent      = "go-github"
+
+	headerRateLimit     = "X-RateLimit-Limit"
+	headerRateRemaining = "X-RateLimit-Remaining"
+	headerRateReset     = "X-RateLimit-Reset"
+	headerOTP           = "X-GitHub-OTP"
+
+	mediaTypeV3                = "application/vnd.github.v3+json"
+	defaultMediaType           = "application/octet-stream"
+	mediaTypeV3SHA             = "application/vnd.github.v3.sha"
+	mediaTypeV3Diff            = "application/vnd.github.v3.diff"
+	mediaTypeV3Patch           = "application/vnd.github.v3.patch"
+	mediaTypeOrgPermissionRepo = "application/vnd.github.v3.repository+json"
+
+	// Media Type values to access preview APIs
+
+	// https://developer.github.com/changes/2014-12-09-new-attributes-for-stars-api/
+	mediaTypeStarringPreview = "application/vnd.github.v3.star+json"
+
+	// https://help.github.com/enterprise/2.4/admin/guides/migrations/exporting-the-github-com-organization-s-repositories/
+	mediaTypeMigrationsPreview = "application/vnd.github.wyandotte-preview+json"
+
+	// https://developer.github.com/changes/2016-04-06-deployment-and-deployment-status-enhancements/
+	mediaTypeDeploymentStatusPreview = "application/vnd.github.ant-man-preview+json"
+
+	// https://developer.github.com/changes/2018-10-16-deployments-environments-states-and-auto-inactive-updates/
+	mediaTypeExpandDeploymentStatusPreview = "application/vnd.github.flash-preview+json"
+
+	// https://developer.github.com/changes/2016-02-19-source-import-preview-api/
+	mediaTypeImportPreview = "application/vnd.github.barred-rock-preview"
+
+	// https://developer.github.com/changes/2016-05-12-reactions-api-preview/
+	mediaTypeReactionsPreview = "application/vnd.github.squirrel-girl-preview"
+
+	// https://developer.github.com/changes/2016-05-23-timeline-preview-api/
+	mediaTypeTimelinePreview = "application/vnd.github.mockingbird-preview+json"
+
+	// https://developer.github.com/changes/2016-07-06-github-pages-preiew-api/
+	mediaTypePagesPreview = "application/vnd.github.mister-fantastic-preview+json"
+
+	// https://developer.github.com/changes/2016-09-14-projects-api/
+	mediaTypeProjectsPreview = "application/vnd.github.inertia-preview+json"
+
+	// https://developer.github.com/changes/2016-09-14-Integrations-Early-Access/
+	mediaTypeIntegrationPreview = "application/vnd.github.machine-man-preview+json"
+
+	// https://developer.github.com/changes/2017-01-05-commit-search-api/
+	mediaTypeCommitSearchPreview = "application/vnd.github.cloak-preview+json"
+
+	// https://developer.github.com/changes/2017-02-28-user-blocking-apis-and-webhook/
+	mediaTypeBlockUsersPreview = "application/vnd.github.giant-sentry-fist-preview+json"
+
+	// https://developer.github.com/changes/2017-02-09-community-health/
+	mediaTypeRepositoryCommunityHealthMetricsPreview = "application/vnd.github.black-panther-preview+json"
+
+	// https://developer.github.com/changes/2017-05-23-coc-api/
+	mediaTypeCodesOfConductPreview = "application/vnd.github.scarlet-witch-preview+json"
+
+	// https://developer.github.com/changes/2017-07-17-update-topics-on-repositories/
+	mediaTypeTopicsPreview = "application/vnd.github.mercy-preview+json"
+
+	// https://developer.github.com/changes/2017-08-30-preview-nested-teams/
+	mediaTypeNestedTeamsPreview = "application/vnd.github.hellcat-preview+json"
+
+	// https://developer.github.com/changes/2017-11-09-repository-transfer-api-preview/
+	mediaTypeRepositoryTransferPreview = "application/vnd.github.nightshade-preview+json"
+
+	// https://developer.github.com/changes/2018-01-25-organization-invitation-api-preview/
+	mediaTypeOrganizationInvitationPreview = "application/vnd.github.dazzler-preview+json"
+
+	// https://developer.github.com/changes/2018-03-16-protected-branches-required-approving-reviews/
+	mediaTypeRequiredApprovingReviewsPreview = "application/vnd.github.luke-cage-preview+json"
+
+	// https://developer.github.com/changes/2018-02-22-label-description-search-preview/
+	mediaTypeLabelDescriptionSearchPreview = "application/vnd.github.symmetra-preview+json"
+
+	// https://developer.github.com/changes/2018-02-07-team-discussions-api/
+	mediaTypeTeamDiscussionsPreview = "application/vnd.github.echo-preview+json"
+
+	// https://developer.github.com/changes/2018-03-21-hovercard-api-preview/
+	mediaTypeHovercardPreview = "application/vnd.github.hagar-preview+json"
+
+	// https://developer.github.com/changes/2018-01-10-lock-reason-api-preview/
+	mediaTypeLockReasonPreview = "application/vnd.github.sailor-v-preview+json"
+
+	// https://developer.github.com/changes/2018-05-07-new-checks-api-public-beta/
+	mediaTypeCheckRunsPreview = "application/vnd.github.antiope-preview+json"
+
+	// https://developer.github.com/enterprise/2.13/v3/repos/pre_receive_hooks/
+	mediaTypePreReceiveHooksPreview = "application/vnd.github.eye-scream-preview"
+
+	// https://developer.github.com/changes/2018-02-22-protected-branches-required-signatures/
+	mediaTypeSignaturePreview = "application/vnd.github.zzzax-preview+json"
+
+	// https://developer.github.com/changes/2018-09-05-project-card-events/
+	mediaTypeProjectCardDetailsPreview = "application/vnd.github.starfox-preview+json"
+
+	// https://developer.github.com/changes/2018-12-18-interactions-preview/
+	mediaTypeInteractionRestrictionsPreview = "application/vnd.github.sombra-preview+json"
+
+	// https://developer.github.com/changes/2019-02-14-draft-pull-requests/
+	mediaTypeDraftPreview = "application/vnd.github.shadow-cat-preview+json"
+)
+
+// A Client manages communication with the GitHub API.
+type Client struct {
+	clientMu sync.Mutex   // clientMu protects the client during calls that modify the CheckRedirect func.
+	client   *http.Client // HTTP client used to communicate with the API.
+
+	// Base URL for API requests. Defaults to the public GitHub API, but can be
+	// set to a domain endpoint to use with GitHub Enterprise. BaseURL should
+	// always be specified with a trailing slash.
+	BaseURL *url.URL
+
+	// Base URL for uploading files.
+	UploadURL *url.URL
+
+	// User agent used when communicating with the GitHub API.
+	UserAgent string
+
+	rateMu     sync.Mutex
+	rateLimits [categories]Rate // Rate limits for the client as determined by the most recent API calls.
+
+	common service // Reuse a single struct instead of allocating one for each service on the heap.
+
+	// Services used for talking to different parts of the GitHub API.
+	Activity       *ActivityService
+	Admin          *AdminService
+	Apps           *AppsService
+	Authorizations *AuthorizationsService
+	Checks         *ChecksService
+	Gists          *GistsService
+	Git            *GitService
+	Gitignores     *GitignoresService
+	Interactions   *InteractionsService
+	Issues         *IssuesService
+	Licenses       *LicensesService
+	Marketplace    *MarketplaceService
+	Migrations     *MigrationService
+	Organizations  *OrganizationsService
+	Projects       *ProjectsService
+	PullRequests   *PullRequestsService
+	Reactions      *ReactionsService
+	Repositories   *RepositoriesService
+	Search         *SearchService
+	Teams          *TeamsService
+	Users          *UsersService
+}
+
+type service struct {
+	client *Client
+}
+
+// ListOptions specifies the optional parameters to various List methods that
+// support pagination.
+type ListOptions struct {
+	// For paginated result sets, page of results to retrieve.
+	Page int `url:"page,omitempty"`
+
+	// For paginated result sets, the number of results to include per page.
+	PerPage int `url:"per_page,omitempty"`
+}
+
+// UploadOptions specifies the parameters to methods that support uploads.
+type UploadOptions struct {
+	Name      string `url:"name,omitempty"`
+	Label     string `url:"label,omitempty"`
+	MediaType string `url:"-"`
+}
+
+// RawType represents type of raw format of a request instead of JSON.
+type RawType uint8
+
+const (
+	// Diff format.
+	Diff RawType = 1 + iota
+	// Patch format.
+	Patch
+)
+
+// RawOptions specifies parameters when user wants to get raw format of
+// a response instead of JSON.
+type RawOptions struct {
+	Type RawType
+}
+
+// addOptions adds the parameters in opt as URL query parameters to s. opt
+// must be a struct whose fields may contain "url" tags.
+func addOptions(s string, opt interface{}) (string, error) {
+	v := reflect.ValueOf(opt)
+	if v.Kind() == reflect.Ptr && v.IsNil() {
+		return s, nil
+	}
+
+	u, err := url.Parse(s)
+	if err != nil {
+		return s, err
+	}
+
+	qs, err := query.Values(opt)
+	if err != nil {
+		return s, err
+	}
+
+	u.RawQuery = qs.Encode()
+	return u.String(), nil
+}
+
+// NewClient returns a new GitHub API client. If a nil httpClient is
+// provided, http.DefaultClient will be used. To use API methods which require
+// authentication, provide an http.Client that will perform the authentication
+// for you (such as that provided by the golang.org/x/oauth2 library).
+func NewClient(httpClient *http.Client) *Client {
+	if httpClient == nil {
+		httpClient = http.DefaultClient
+	}
+	baseURL, _ := url.Parse(defaultBaseURL)
+	uploadURL, _ := url.Parse(uploadBaseURL)
+
+	c := &Client{client: httpClient, BaseURL: baseURL, UserAgent: userAgent, UploadURL: uploadURL}
+	c.common.client = c
+	c.Activity = (*ActivityService)(&c.common)
+	c.Admin = (*AdminService)(&c.common)
+	c.Apps = (*AppsService)(&c.common)
+	c.Authorizations = (*AuthorizationsService)(&c.common)
+	c.Checks = (*ChecksService)(&c.common)
+	c.Gists = (*GistsService)(&c.common)
+	c.Git = (*GitService)(&c.common)
+	c.Gitignores = (*GitignoresService)(&c.common)
+	c.Interactions = (*InteractionsService)(&c.common)
+	c.Issues = (*IssuesService)(&c.common)
+	c.Licenses = (*LicensesService)(&c.common)
+	c.Marketplace = &MarketplaceService{client: c}
+	c.Migrations = (*MigrationService)(&c.common)
+	c.Organizations = (*OrganizationsService)(&c.common)
+	c.Projects = (*ProjectsService)(&c.common)
+	c.PullRequests = (*PullRequestsService)(&c.common)
+	c.Reactions = (*ReactionsService)(&c.common)
+	c.Repositories = (*RepositoriesService)(&c.common)
+	c.Search = (*SearchService)(&c.common)
+	c.Teams = (*TeamsService)(&c.common)
+	c.Users = (*UsersService)(&c.common)
+	return c
+}
+
+// NewEnterpriseClient returns a new GitHub API client with provided
+// base URL and upload URL (often the same URL).
+// If either URL does not have a trailing slash, one is added automatically.
+// If a nil httpClient is provided, http.DefaultClient will be used.
+//
+// Note that NewEnterpriseClient is a convenience helper only;
+// its behavior is equivalent to using NewClient, followed by setting
+// the BaseURL and UploadURL fields.
+func NewEnterpriseClient(baseURL, uploadURL string, httpClient *http.Client) (*Client, error) {
+	baseEndpoint, err := url.Parse(baseURL)
+	if err != nil {
+		return nil, err
+	}
+	if !strings.HasSuffix(baseEndpoint.Path, "/") {
+		baseEndpoint.Path += "/"
+	}
+
+	uploadEndpoint, err := url.Parse(uploadURL)
+	if err != nil {
+		return nil, err
+	}
+	if !strings.HasSuffix(uploadEndpoint.Path, "/") {
+		uploadEndpoint.Path += "/"
+	}
+
+	c := NewClient(httpClient)
+	c.BaseURL = baseEndpoint
+	c.UploadURL = uploadEndpoint
+	return c, nil
+}
+
+// NewRequest creates an API request. A relative URL can be provided in urlStr,
+// in which case it is resolved relative to the BaseURL of the Client.
+// Relative URLs should always be specified without a preceding slash. If
+// specified, the value pointed to by body is JSON encoded and included as the
+// request body.
+func (c *Client) NewRequest(method, urlStr string, body interface{}) (*http.Request, error) {
+	if !strings.HasSuffix(c.BaseURL.Path, "/") {
+		return nil, fmt.Errorf("BaseURL must have a trailing slash, but %q does not", c.BaseURL)
+	}
+	u, err := c.BaseURL.Parse(urlStr)
+	if err != nil {
+		return nil, err
+	}
+
+	var buf io.ReadWriter
+	if body != nil {
+		buf = new(bytes.Buffer)
+		enc := json.NewEncoder(buf)
+		enc.SetEscapeHTML(false)
+		err := enc.Encode(body)
+		if err != nil {
+			return nil, err
+		}
+	}
+
+	req, err := http.NewRequest(method, u.String(), buf)
+	if err != nil {
+		return nil, err
+	}
+
+	if body != nil {
+		req.Header.Set("Content-Type", "application/json")
+	}
+	req.Header.Set("Accept", mediaTypeV3)
+	if c.UserAgent != "" {
+		req.Header.Set("User-Agent", c.UserAgent)
+	}
+	return req, nil
+}
+
+// NewUploadRequest creates an upload request. A relative URL can be provided in
+// urlStr, in which case it is resolved relative to the UploadURL of the Client.
+// Relative URLs should always be specified without a preceding slash.
+func (c *Client) NewUploadRequest(urlStr string, reader io.Reader, size int64, mediaType string) (*http.Request, error) {
+	if !strings.HasSuffix(c.UploadURL.Path, "/") {
+		return nil, fmt.Errorf("UploadURL must have a trailing slash, but %q does not", c.UploadURL)
+	}
+	u, err := c.UploadURL.Parse(urlStr)
+	if err != nil {
+		return nil, err
+	}
+
+	req, err := http.NewRequest("POST", u.String(), reader)
+	if err != nil {
+		return nil, err
+	}
+	req.ContentLength = size
+
+	if mediaType == "" {
+		mediaType = defaultMediaType
+	}
+	req.Header.Set("Content-Type", mediaType)
+	req.Header.Set("Accept", mediaTypeV3)
+	req.Header.Set("User-Agent", c.UserAgent)
+	return req, nil
+}
+
+// Response is a GitHub API response. This wraps the standard http.Response
+// returned from GitHub and provides convenient access to things like
+// pagination links.
+type Response struct {
+	*http.Response
+
+	// These fields provide the page values for paginating through a set of
+	// results. Any or all of these may be set to the zero value for
+	// responses that are not part of a paginated set, or for which there
+	// are no additional pages.
+
+	NextPage  int
+	PrevPage  int
+	FirstPage int
+	LastPage  int
+
+	// Explicitly specify the Rate type so Rate's String() receiver doesn't
+	// propagate to Response.
+	Rate Rate
+}
+
+// newResponse creates a new Response for the provided http.Response.
+// r must not be nil.
+func newResponse(r *http.Response) *Response {
+	response := &Response{Response: r}
+	response.populatePageValues()
+	response.Rate = parseRate(r)
+	return response
+}
+
+// populatePageValues parses the HTTP Link response headers and populates the
+// various pagination link values in the Response.
+func (r *Response) populatePageValues() {
+	if links, ok := r.Response.Header["Link"]; ok && len(links) > 0 {
+		for _, link := range strings.Split(links[0], ",") {
+			segments := strings.Split(strings.TrimSpace(link), ";")
+
+			// link must at least have href and rel
+			if len(segments) < 2 {
+				continue
+			}
+
+			// ensure href is properly formatted
+			if !strings.HasPrefix(segments[0], "<") || !strings.HasSuffix(segments[0], ">") {
+				continue
+			}
+
+			// try to pull out page parameter
+			url, err := url.Parse(segments[0][1 : len(segments[0])-1])
+			if err != nil {
+				continue
+			}
+			page := url.Query().Get("page")
+			if page == "" {
+				continue
+			}
+
+			for _, segment := range segments[1:] {
+				switch strings.TrimSpace(segment) {
+				case `rel="next"`:
+					r.NextPage, _ = strconv.Atoi(page)
+				case `rel="prev"`:
+					r.PrevPage, _ = strconv.Atoi(page)
+				case `rel="first"`:
+					r.FirstPage, _ = strconv.Atoi(page)
+				case `rel="last"`:
+					r.LastPage, _ = strconv.Atoi(page)
+				}
+
+			}
+		}
+	}
+}
+
+// parseRate parses the rate related headers.
+func parseRate(r *http.Response) Rate {
+	var rate Rate
+	if limit := r.Header.Get(headerRateLimit); limit != "" {
+		rate.Limit, _ = strconv.Atoi(limit)
+	}
+	if remaining := r.Header.Get(headerRateRemaining); remaining != "" {
+		rate.Remaining, _ = strconv.Atoi(remaining)
+	}
+	if reset := r.Header.Get(headerRateReset); reset != "" {
+		if v, _ := strconv.ParseInt(reset, 10, 64); v != 0 {
+			rate.Reset = Timestamp{time.Unix(v, 0)}
+		}
+	}
+	return rate
+}
+
+// Do sends an API request and returns the API response. The API response is
+// JSON decoded and stored in the value pointed to by v, or returned as an
+// error if an API error has occurred. If v implements the io.Writer
+// interface, the raw response body will be written to v, without attempting to
+// first decode it. If rate limit is exceeded and reset time is in the future,
+// Do returns *RateLimitError immediately without making a network API call.
+//
+// The provided ctx must be non-nil. If it is canceled or times out,
+// ctx.Err() will be returned.
+func (c *Client) Do(ctx context.Context, req *http.Request, v interface{}) (*Response, error) {
+	req = withContext(ctx, req)
+
+	rateLimitCategory := category(req.URL.Path)
+
+	// If we've hit rate limit, don't make further requests before Reset time.
+	if err := c.checkRateLimitBeforeDo(req, rateLimitCategory); err != nil {
+		return &Response{
+			Response: err.Response,
+			Rate:     err.Rate,
+		}, err
+	}
+
+	resp, err := c.client.Do(req)
+	if err != nil {
+		// If we got an error, and the context has been canceled,
+		// the context's error is probably more useful.
+		select {
+		case <-ctx.Done():
+			return nil, ctx.Err()
+		default:
+		}
+
+		// If the error type is *url.Error, sanitize its URL before returning.
+		if e, ok := err.(*url.Error); ok {
+			if url, err := url.Parse(e.URL); err == nil {
+				e.URL = sanitizeURL(url).String()
+				return nil, e
+			}
+		}
+
+		return nil, err
+	}
+	defer resp.Body.Close()
+
+	response := newResponse(resp)
+
+	c.rateMu.Lock()
+	c.rateLimits[rateLimitCategory] = response.Rate
+	c.rateMu.Unlock()
+
+	err = CheckResponse(resp)
+	if err != nil {
+		// Special case for AcceptedErrors. If an AcceptedError
+		// has been encountered, the response's payload will be
+		// added to the AcceptedError and returned.
+		//
+		// Issue #1022
+		aerr, ok := err.(*AcceptedError)
+		if ok {
+			b, readErr := ioutil.ReadAll(resp.Body)
+			if readErr != nil {
+				return response, readErr
+			}
+
+			aerr.Raw = b
+			return response, aerr
+		}
+
+		return response, err
+	}
+
+	if v != nil {
+		if w, ok := v.(io.Writer); ok {
+			io.Copy(w, resp.Body)
+		} else {
+			decErr := json.NewDecoder(resp.Body).Decode(v)
+			if decErr == io.EOF {
+				decErr = nil // ignore EOF errors caused by empty response body
+			}
+			if decErr != nil {
+				err = decErr
+			}
+		}
+	}
+
+	return response, err
+}
+
+// checkRateLimitBeforeDo does not make any network calls, but uses existing knowledge from
+// current client state in order to quickly check if *RateLimitError can be immediately returned
+// from Client.Do, and if so, returns it so that Client.Do can skip making a network API call unnecessarily.
+// Otherwise it returns nil, and Client.Do should proceed normally.
+func (c *Client) checkRateLimitBeforeDo(req *http.Request, rateLimitCategory rateLimitCategory) *RateLimitError {
+	c.rateMu.Lock()
+	rate := c.rateLimits[rateLimitCategory]
+	c.rateMu.Unlock()
+	if !rate.Reset.Time.IsZero() && rate.Remaining == 0 && time.Now().Before(rate.Reset.Time) {
+		// Create a fake response.
+		resp := &http.Response{
+			Status:     http.StatusText(http.StatusForbidden),
+			StatusCode: http.StatusForbidden,
+			Request:    req,
+			Header:     make(http.Header),
+			Body:       ioutil.NopCloser(strings.NewReader("")),
+		}
+		return &RateLimitError{
+			Rate:     rate,
+			Response: resp,
+			Message:  fmt.Sprintf("API rate limit of %v still exceeded until %v, not making remote request.", rate.Limit, rate.Reset.Time),
+		}
+	}
+
+	return nil
+}
+
+/*
+An ErrorResponse reports one or more errors caused by an API request.
+
+GitHub API docs: https://developer.github.com/v3/#client-errors
+*/
+type ErrorResponse struct {
+	Response *http.Response // HTTP response that caused this error
+	Message  string         `json:"message"` // error message
+	Errors   []Error        `json:"errors"`  // more detail on individual errors
+	// Block is only populated on certain types of errors such as code 451.
+	// See https://developer.github.com/changes/2016-03-17-the-451-status-code-is-now-supported/
+	// for more information.
+	Block *struct {
+		Reason    string     `json:"reason,omitempty"`
+		CreatedAt *Timestamp `json:"created_at,omitempty"`
+	} `json:"block,omitempty"`
+	// Most errors will also include a documentation_url field pointing
+	// to some content that might help you resolve the error, see
+	// https://developer.github.com/v3/#client-errors
+	DocumentationURL string `json:"documentation_url,omitempty"`
+}
+
+func (r *ErrorResponse) Error() string {
+	return fmt.Sprintf("%v %v: %d %v %+v",
+		r.Response.Request.Method, sanitizeURL(r.Response.Request.URL),
+		r.Response.StatusCode, r.Message, r.Errors)
+}
+
+// TwoFactorAuthError occurs when using HTTP Basic Authentication for a user
+// that has two-factor authentication enabled. The request can be reattempted
+// by providing a one-time password in the request.
+type TwoFactorAuthError ErrorResponse
+
+func (r *TwoFactorAuthError) Error() string { return (*ErrorResponse)(r).Error() }
+
+// RateLimitError occurs when GitHub returns 403 Forbidden response with a rate limit
+// remaining value of 0, and error message starts with "API rate limit exceeded for ".
+type RateLimitError struct {
+	Rate     Rate           // Rate specifies last known rate limit for the client
+	Response *http.Response // HTTP response that caused this error
+	Message  string         `json:"message"` // error message
+}
+
+func (r *RateLimitError) Error() string {
+	return fmt.Sprintf("%v %v: %d %v %v",
+		r.Response.Request.Method, sanitizeURL(r.Response.Request.URL),
+		r.Response.StatusCode, r.Message, formatRateReset(r.Rate.Reset.Time.Sub(time.Now())))
+}
+
+// AcceptedError occurs when GitHub returns 202 Accepted response with an
+// empty body, which means a job was scheduled on the GitHub side to process
+// the information needed and cache it.
+// Technically, 202 Accepted is not a real error, it's just used to
+// indicate that results are not ready yet, but should be available soon.
+// The request can be repeated after some time.
+type AcceptedError struct {
+	// Raw contains the response body.
+	Raw []byte
+}
+
+func (*AcceptedError) Error() string {
+	return "job scheduled on GitHub side; try again later"
+}
+
+// AbuseRateLimitError occurs when GitHub returns 403 Forbidden response with the
+// "documentation_url" field value equal to "https://developer.github.com/v3/#abuse-rate-limits".
+type AbuseRateLimitError struct {
+	Response *http.Response // HTTP response that caused this error
+	Message  string         `json:"message"` // error message
+
+	// RetryAfter is provided with some abuse rate limit errors. If present,
+	// it is the amount of time that the client should wait before retrying.
+	// Otherwise, the client should try again later (after an unspecified amount of time).
+	RetryAfter *time.Duration
+}
+
+func (r *AbuseRateLimitError) Error() string {
+	return fmt.Sprintf("%v %v: %d %v",
+		r.Response.Request.Method, sanitizeURL(r.Response.Request.URL),
+		r.Response.StatusCode, r.Message)
+}
+
+// sanitizeURL redacts the client_secret parameter from the URL which may be
+// exposed to the user.
+func sanitizeURL(uri *url.URL) *url.URL {
+	if uri == nil {
+		return nil
+	}
+	params := uri.Query()
+	if len(params.Get("client_secret")) > 0 {
+		params.Set("client_secret", "REDACTED")
+		uri.RawQuery = params.Encode()
+	}
+	return uri
+}
+
+/*
+An Error reports more details on an individual error in an ErrorResponse.
+These are the possible validation error codes:
+
+    missing:
+        resource does not exist
+    missing_field:
+        a required field on a resource has not been set
+    invalid:
+        the formatting of a field is invalid
+    already_exists:
+        another resource has the same valid as this field
+    custom:
+        some resources return this (e.g. github.User.CreateKey()), additional
+        information is set in the Message field of the Error
+
+GitHub API docs: https://developer.github.com/v3/#client-errors
+*/
+type Error struct {
+	Resource string `json:"resource"` // resource on which the error occurred
+	Field    string `json:"field"`    // field on which the error occurred
+	Code     string `json:"code"`     // validation error code
+	Message  string `json:"message"`  // Message describing the error. Errors with Code == "custom" will always have this set.
+}
+
+func (e *Error) Error() string {
+	return fmt.Sprintf("%v error caused by %v field on %v resource",
+		e.Code, e.Field, e.Resource)
+}
+
+// CheckResponse checks the API response for errors, and returns them if
+// present. A response is considered an error if it has a status code outside
+// the 200 range or equal to 202 Accepted.
+// API error responses are expected to have either no response
+// body, or a JSON response body that maps to ErrorResponse. Any other
+// response body will be silently ignored.
+//
+// The error type will be *RateLimitError for rate limit exceeded errors,
+// *AcceptedError for 202 Accepted status codes,
+// and *TwoFactorAuthError for two-factor authentication errors.
+func CheckResponse(r *http.Response) error {
+	if r.StatusCode == http.StatusAccepted {
+		return &AcceptedError{}
+	}
+	if c := r.StatusCode; 200 <= c && c <= 299 {
+		return nil
+	}
+	errorResponse := &ErrorResponse{Response: r}
+	data, err := ioutil.ReadAll(r.Body)
+	if err == nil && data != nil {
+		json.Unmarshal(data, errorResponse)
+	}
+	switch {
+	case r.StatusCode == http.StatusUnauthorized && strings.HasPrefix(r.Header.Get(headerOTP), "required"):
+		return (*TwoFactorAuthError)(errorResponse)
+	case r.StatusCode == http.StatusForbidden && r.Header.Get(headerRateRemaining) == "0" && strings.HasPrefix(errorResponse.Message, "API rate limit exceeded for "):
+		return &RateLimitError{
+			Rate:     parseRate(r),
+			Response: errorResponse.Response,
+			Message:  errorResponse.Message,
+		}
+	case r.StatusCode == http.StatusForbidden && strings.HasSuffix(errorResponse.DocumentationURL, "/v3/#abuse-rate-limits"):
+		abuseRateLimitError := &AbuseRateLimitError{
+			Response: errorResponse.Response,
+			Message:  errorResponse.Message,
+		}
+		if v := r.Header["Retry-After"]; len(v) > 0 {
+			// According to GitHub support, the "Retry-After" header value will be
+			// an integer which represents the number of seconds that one should
+			// wait before resuming making requests.
+			retryAfterSeconds, _ := strconv.ParseInt(v[0], 10, 64) // Error handling is noop.
+			retryAfter := time.Duration(retryAfterSeconds) * time.Second
+			abuseRateLimitError.RetryAfter = &retryAfter
+		}
+		return abuseRateLimitError
+	default:
+		return errorResponse
+	}
+}
+
+// parseBoolResponse determines the boolean result from a GitHub API response.
+// Several GitHub API methods return boolean responses indicated by the HTTP
+// status code in the response (true indicated by a 204, false indicated by a
+// 404). This helper function will determine that result and hide the 404
+// error if present. Any other error will be returned through as-is.
+func parseBoolResponse(err error) (bool, error) {
+	if err == nil {
+		return true, nil
+	}
+
+	if err, ok := err.(*ErrorResponse); ok && err.Response.StatusCode == http.StatusNotFound {
+		// Simply false. In this one case, we do not pass the error through.
+		return false, nil
+	}
+
+	// some other real error occurred
+	return false, err
+}
+
+// Rate represents the rate limit for the current client.
+type Rate struct {
+	// The number of requests per hour the client is currently limited to.
+	Limit int `json:"limit"`
+
+	// The number of remaining requests the client can make this hour.
+	Remaining int `json:"remaining"`
+
+	// The time at which the current rate limit will reset.
+	Reset Timestamp `json:"reset"`
+}
+
+func (r Rate) String() string {
+	return Stringify(r)
+}
+
+// RateLimits represents the rate limits for the current client.
+type RateLimits struct {
+	// The rate limit for non-search API requests. Unauthenticated
+	// requests are limited to 60 per hour. Authenticated requests are
+	// limited to 5,000 per hour.
+	//
+	// GitHub API docs: https://developer.github.com/v3/#rate-limiting
+	Core *Rate `json:"core"`
+
+	// The rate limit for search API requests. Unauthenticated requests
+	// are limited to 10 requests per minutes. Authenticated requests are
+	// limited to 30 per minute.
+	//
+	// GitHub API docs: https://developer.github.com/v3/search/#rate-limit
+	Search *Rate `json:"search"`
+}
+
+func (r RateLimits) String() string {
+	return Stringify(r)
+}
+
+type rateLimitCategory uint8
+
+const (
+	coreCategory rateLimitCategory = iota
+	searchCategory
+
+	categories // An array of this length will be able to contain all rate limit categories.
+)
+
+// category returns the rate limit category of the endpoint, determined by Request.URL.Path.
+func category(path string) rateLimitCategory {
+	switch {
+	default:
+		return coreCategory
+	case strings.HasPrefix(path, "/search/"):
+		return searchCategory
+	}
+}
+
+// RateLimits returns the rate limits for the current client.
+func (c *Client) RateLimits(ctx context.Context) (*RateLimits, *Response, error) {
+	req, err := c.NewRequest("GET", "rate_limit", nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	response := new(struct {
+		Resources *RateLimits `json:"resources"`
+	})
+	resp, err := c.Do(ctx, req, response)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	if response.Resources != nil {
+		c.rateMu.Lock()
+		if response.Resources.Core != nil {
+			c.rateLimits[coreCategory] = *response.Resources.Core
+		}
+		if response.Resources.Search != nil {
+			c.rateLimits[searchCategory] = *response.Resources.Search
+		}
+		c.rateMu.Unlock()
+	}
+
+	return response.Resources, resp, nil
+}
+
+/*
+UnauthenticatedRateLimitedTransport allows you to make unauthenticated calls
+that need to use a higher rate limit associated with your OAuth application.
+
+	t := &github.UnauthenticatedRateLimitedTransport{
+		ClientID:     "your app's client ID",
+		ClientSecret: "your app's client secret",
+	}
+	client := github.NewClient(t.Client())
+
+This will append the querystring params client_id=xxx&client_secret=yyy to all
+requests.
+
+See https://developer.github.com/v3/#unauthenticated-rate-limited-requests for
+more information.
+*/
+type UnauthenticatedRateLimitedTransport struct {
+	// ClientID is the GitHub OAuth client ID of the current application, which
+	// can be found by selecting its entry in the list at
+	// https://github.com/settings/applications.
+	ClientID string
+
+	// ClientSecret is the GitHub OAuth client secret of the current
+	// application.
+	ClientSecret string
+
+	// Transport is the underlying HTTP transport to use when making requests.
+	// It will default to http.DefaultTransport if nil.
+	Transport http.RoundTripper
+}
+
+// RoundTrip implements the RoundTripper interface.
+func (t *UnauthenticatedRateLimitedTransport) RoundTrip(req *http.Request) (*http.Response, error) {
+	if t.ClientID == "" {
+		return nil, errors.New("t.ClientID is empty")
+	}
+	if t.ClientSecret == "" {
+		return nil, errors.New("t.ClientSecret is empty")
+	}
+
+	// To set extra querystring params, we must make a copy of the Request so
+	// that we don't modify the Request we were given. This is required by the
+	// specification of http.RoundTripper.
+	//
+	// Since we are going to modify only req.URL here, we only need a deep copy
+	// of req.URL.
+	req2 := new(http.Request)
+	*req2 = *req
+	req2.URL = new(url.URL)
+	*req2.URL = *req.URL
+
+	q := req2.URL.Query()
+	q.Set("client_id", t.ClientID)
+	q.Set("client_secret", t.ClientSecret)
+	req2.URL.RawQuery = q.Encode()
+
+	// Make the HTTP request.
+	return t.transport().RoundTrip(req2)
+}
+
+// Client returns an *http.Client that makes requests which are subject to the
+// rate limit of your OAuth application.
+func (t *UnauthenticatedRateLimitedTransport) Client() *http.Client {
+	return &http.Client{Transport: t}
+}
+
+func (t *UnauthenticatedRateLimitedTransport) transport() http.RoundTripper {
+	if t.Transport != nil {
+		return t.Transport
+	}
+	return http.DefaultTransport
+}
+
+// BasicAuthTransport is an http.RoundTripper that authenticates all requests
+// using HTTP Basic Authentication with the provided username and password. It
+// additionally supports users who have two-factor authentication enabled on
+// their GitHub account.
+type BasicAuthTransport struct {
+	Username string // GitHub username
+	Password string // GitHub password
+	OTP      string // one-time password for users with two-factor auth enabled
+
+	// Transport is the underlying HTTP transport to use when making requests.
+	// It will default to http.DefaultTransport if nil.
+	Transport http.RoundTripper
+}
+
+// RoundTrip implements the RoundTripper interface.
+func (t *BasicAuthTransport) RoundTrip(req *http.Request) (*http.Response, error) {
+	// To set extra headers, we must make a copy of the Request so
+	// that we don't modify the Request we were given. This is required by the
+	// specification of http.RoundTripper.
+	//
+	// Since we are going to modify only req.Header here, we only need a deep copy
+	// of req.Header.
+	req2 := new(http.Request)
+	*req2 = *req
+	req2.Header = make(http.Header, len(req.Header))
+	for k, s := range req.Header {
+		req2.Header[k] = append([]string(nil), s...)
+	}
+
+	req2.SetBasicAuth(t.Username, t.Password)
+	if t.OTP != "" {
+		req2.Header.Set(headerOTP, t.OTP)
+	}
+	return t.transport().RoundTrip(req2)
+}
+
+// Client returns an *http.Client that makes requests that are authenticated
+// using HTTP Basic Authentication.
+func (t *BasicAuthTransport) Client() *http.Client {
+	return &http.Client{Transport: t}
+}
+
+func (t *BasicAuthTransport) transport() http.RoundTripper {
+	if t.Transport != nil {
+		return t.Transport
+	}
+	return http.DefaultTransport
+}
+
+// formatRateReset formats d to look like "[rate reset in 2s]" or
+// "[rate reset in 87m02s]" for the positive durations. And like "[rate limit was reset 87m02s ago]"
+// for the negative cases.
+func formatRateReset(d time.Duration) string {
+	isNegative := d < 0
+	if isNegative {
+		d *= -1
+	}
+	secondsTotal := int(0.5 + d.Seconds())
+	minutes := secondsTotal / 60
+	seconds := secondsTotal - minutes*60
+
+	var timeString string
+	if minutes > 0 {
+		timeString = fmt.Sprintf("%dm%02ds", minutes, seconds)
+	} else {
+		timeString = fmt.Sprintf("%ds", seconds)
+	}
+
+	if isNegative {
+		return fmt.Sprintf("[rate limit was reset %v ago]", timeString)
+	}
+	return fmt.Sprintf("[rate reset in %v]", timeString)
+}
+
+// Bool is a helper routine that allocates a new bool value
+// to store v and returns a pointer to it.
+func Bool(v bool) *bool { return &v }
+
+// Int is a helper routine that allocates a new int value
+// to store v and returns a pointer to it.
+func Int(v int) *int { return &v }
+
+// Int64 is a helper routine that allocates a new int64 value
+// to store v and returns a pointer to it.
+func Int64(v int64) *int64 { return &v }
+
+// String is a helper routine that allocates a new string value
+// to store v and returns a pointer to it.
+func String(v string) *string { return &v }
diff --git a/vendor/github.com/google/go-github/v24/github/gitignore.go b/vendor/github.com/google/go-github/v24/github/gitignore.go
new file mode 100644
index 000000000..2f691bc32
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/gitignore.go
@@ -0,0 +1,64 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// GitignoresService provides access to the gitignore related functions in the
+// GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/gitignore/
+type GitignoresService service
+
+// Gitignore represents a .gitignore file as returned by the GitHub API.
+type Gitignore struct {
+	Name   *string `json:"name,omitempty"`
+	Source *string `json:"source,omitempty"`
+}
+
+func (g Gitignore) String() string {
+	return Stringify(g)
+}
+
+// List all available Gitignore templates.
+//
+// GitHub API docs: https://developer.github.com/v3/gitignore/#listing-available-templates
+func (s GitignoresService) List(ctx context.Context) ([]string, *Response, error) {
+	req, err := s.client.NewRequest("GET", "gitignore/templates", nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var availableTemplates []string
+	resp, err := s.client.Do(ctx, req, &availableTemplates)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return availableTemplates, resp, nil
+}
+
+// Get a Gitignore by name.
+//
+// GitHub API docs: https://developer.github.com/v3/gitignore/#get-a-single-template
+func (s GitignoresService) Get(ctx context.Context, name string) (*Gitignore, *Response, error) {
+	u := fmt.Sprintf("gitignore/templates/%v", name)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	gitignore := new(Gitignore)
+	resp, err := s.client.Do(ctx, req, gitignore)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return gitignore, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/interactions.go b/vendor/github.com/google/go-github/v24/github/interactions.go
new file mode 100644
index 000000000..b9965491d
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/interactions.go
@@ -0,0 +1,28 @@
+// Copyright 2018 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+// InteractionsService handles communication with the repository and organization related
+// methods of the GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/interactions/
+type InteractionsService service
+
+// InteractionRestriction represents the interaction restrictions for repository and organization.
+type InteractionRestriction struct {
+	// Specifies the group of GitHub users who can
+	// comment, open issues, or create pull requests for the given repository.
+	// Possible values are: "existing_users", "contributors_only" and "collaborators_only".
+	Limit *string `json:"limit,omitempty"`
+
+	// Origin specifies the type of the resource to interact with.
+	// Possible values are: "repository" and "organization".
+	Origin *string `json:"origin,omitempty"`
+
+	// ExpiresAt specifies the time after which the interaction restrictions expire.
+	// The default expiry time is 24 hours from the time restriction is created.
+	ExpiresAt *Timestamp `json:"expires_at,omitempty"`
+}
diff --git a/vendor/github.com/google/go-github/v24/github/interactions_orgs.go b/vendor/github.com/google/go-github/v24/github/interactions_orgs.go
new file mode 100644
index 000000000..af25f6567
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/interactions_orgs.go
@@ -0,0 +1,80 @@
+// Copyright 2019 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// GetRestrictionsForOrg fetches the interaction restrictions for an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/interactions/orgs/#get-interaction-restrictions-for-an-organization
+func (s *InteractionsService) GetRestrictionsForOrg(ctx context.Context, organization string) (*InteractionRestriction, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/interaction-limits", organization)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeInteractionRestrictionsPreview)
+
+	organizationInteractions := new(InteractionRestriction)
+
+	resp, err := s.client.Do(ctx, req, organizationInteractions)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return organizationInteractions, resp, nil
+}
+
+// UpdateRestrictionsForOrg adds or updates the interaction restrictions for an organization.
+//
+// limit specifies the group of GitHub users who can comment, open issues, or create pull requests
+// in public repositories for the given organization.
+// Possible values are: "existing_users", "contributors_only", "collaborators_only".
+//
+// GitHub API docs: https://developer.github.com/v3/interactions/orgs/#add-or-update-interaction-restrictions-for-an-organization
+func (s *InteractionsService) UpdateRestrictionsForOrg(ctx context.Context, organization, limit string) (*InteractionRestriction, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/interaction-limits", organization)
+
+	interaction := &InteractionRestriction{Limit: String(limit)}
+
+	req, err := s.client.NewRequest("PUT", u, interaction)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeInteractionRestrictionsPreview)
+
+	organizationInteractions := new(InteractionRestriction)
+
+	resp, err := s.client.Do(ctx, req, organizationInteractions)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return organizationInteractions, resp, nil
+}
+
+// RemoveRestrictionsFromOrg removes the interaction restrictions for an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/interactions/orgs/#remove-interaction-restrictions-for-an-organization
+func (s *InteractionsService) RemoveRestrictionsFromOrg(ctx context.Context, organization string) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/interaction-limits", organization)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeInteractionRestrictionsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/interactions_repos.go b/vendor/github.com/google/go-github/v24/github/interactions_repos.go
new file mode 100644
index 000000000..58234822f
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/interactions_repos.go
@@ -0,0 +1,80 @@
+// Copyright 2018 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// GetRestrictionsForRepo fetches the interaction restrictions for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/interactions/repos/#get-interaction-restrictions-for-a-repository
+func (s *InteractionsService) GetRestrictionsForRepo(ctx context.Context, owner, repo string) (*InteractionRestriction, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/interaction-limits", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeInteractionRestrictionsPreview)
+
+	repositoryInteractions := new(InteractionRestriction)
+
+	resp, err := s.client.Do(ctx, req, repositoryInteractions)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return repositoryInteractions, resp, nil
+}
+
+// UpdateRestrictionsForRepo adds or updates the interaction restrictions for a repository.
+//
+// limit specifies the group of GitHub users who can comment, open issues, or create pull requests
+// for the given repository.
+// Possible values are: "existing_users", "contributors_only", "collaborators_only".
+//
+// GitHub API docs: https://developer.github.com/v3/interactions/repos/#add-or-update-interaction-restrictions-for-a-repository
+func (s *InteractionsService) UpdateRestrictionsForRepo(ctx context.Context, owner, repo, limit string) (*InteractionRestriction, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/interaction-limits", owner, repo)
+
+	interaction := &InteractionRestriction{Limit: String(limit)}
+
+	req, err := s.client.NewRequest("PUT", u, interaction)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeInteractionRestrictionsPreview)
+
+	repositoryInteractions := new(InteractionRestriction)
+
+	resp, err := s.client.Do(ctx, req, repositoryInteractions)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return repositoryInteractions, resp, nil
+}
+
+// RemoveRestrictionsFromRepo removes the interaction restrictions for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/interactions/repos/#remove-interaction-restrictions-for-a-repository
+func (s *InteractionsService) RemoveRestrictionsFromRepo(ctx context.Context, owner, repo string) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/interaction-limits", owner, repo)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeInteractionRestrictionsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/issues.go b/vendor/github.com/google/go-github/v24/github/issues.go
new file mode 100644
index 000000000..1e0991ce4
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/issues.go
@@ -0,0 +1,347 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"strings"
+	"time"
+)
+
+// IssuesService handles communication with the issue related
+// methods of the GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/
+type IssuesService service
+
+// Issue represents a GitHub issue on a repository.
+//
+// Note: As far as the GitHub API is concerned, every pull request is an issue,
+// but not every issue is a pull request. Some endpoints, events, and webhooks
+// may also return pull requests via this struct. If PullRequestLinks is nil,
+// this is an issue, and if PullRequestLinks is not nil, this is a pull request.
+// The IsPullRequest helper method can be used to check that.
+type Issue struct {
+	ID               *int64            `json:"id,omitempty"`
+	Number           *int              `json:"number,omitempty"`
+	State            *string           `json:"state,omitempty"`
+	Locked           *bool             `json:"locked,omitempty"`
+	Title            *string           `json:"title,omitempty"`
+	Body             *string           `json:"body,omitempty"`
+	User             *User             `json:"user,omitempty"`
+	Labels           []Label           `json:"labels,omitempty"`
+	Assignee         *User             `json:"assignee,omitempty"`
+	Comments         *int              `json:"comments,omitempty"`
+	ClosedAt         *time.Time        `json:"closed_at,omitempty"`
+	CreatedAt        *time.Time        `json:"created_at,omitempty"`
+	UpdatedAt        *time.Time        `json:"updated_at,omitempty"`
+	ClosedBy         *User             `json:"closed_by,omitempty"`
+	URL              *string           `json:"url,omitempty"`
+	HTMLURL          *string           `json:"html_url,omitempty"`
+	CommentsURL      *string           `json:"comments_url,omitempty"`
+	EventsURL        *string           `json:"events_url,omitempty"`
+	LabelsURL        *string           `json:"labels_url,omitempty"`
+	RepositoryURL    *string           `json:"repository_url,omitempty"`
+	Milestone        *Milestone        `json:"milestone,omitempty"`
+	PullRequestLinks *PullRequestLinks `json:"pull_request,omitempty"`
+	Repository       *Repository       `json:"repository,omitempty"`
+	Reactions        *Reactions        `json:"reactions,omitempty"`
+	Assignees        []*User           `json:"assignees,omitempty"`
+	NodeID           *string           `json:"node_id,omitempty"`
+
+	// TextMatches is only populated from search results that request text matches
+	// See: search.go and https://developer.github.com/v3/search/#text-match-metadata
+	TextMatches []TextMatch `json:"text_matches,omitempty"`
+
+	// ActiveLockReason is populated only when LockReason is provided while locking the issue.
+	// Possible values are: "off-topic", "too heated", "resolved", and "spam".
+	ActiveLockReason *string `json:"active_lock_reason,omitempty"`
+}
+
+func (i Issue) String() string {
+	return Stringify(i)
+}
+
+// IsPullRequest reports whether the issue is also a pull request. It uses the
+// method recommended by GitHub's API documentation, which is to check whether
+// PullRequestLinks is non-nil.
+func (i Issue) IsPullRequest() bool {
+	return i.PullRequestLinks != nil
+}
+
+// IssueRequest represents a request to create/edit an issue.
+// It is separate from Issue above because otherwise Labels
+// and Assignee fail to serialize to the correct JSON.
+type IssueRequest struct {
+	Title     *string   `json:"title,omitempty"`
+	Body      *string   `json:"body,omitempty"`
+	Labels    *[]string `json:"labels,omitempty"`
+	Assignee  *string   `json:"assignee,omitempty"`
+	State     *string   `json:"state,omitempty"`
+	Milestone *int      `json:"milestone,omitempty"`
+	Assignees *[]string `json:"assignees,omitempty"`
+}
+
+// IssueListOptions specifies the optional parameters to the IssuesService.List
+// and IssuesService.ListByOrg methods.
+type IssueListOptions struct {
+	// Filter specifies which issues to list. Possible values are: assigned,
+	// created, mentioned, subscribed, all. Default is "assigned".
+	Filter string `url:"filter,omitempty"`
+
+	// State filters issues based on their state. Possible values are: open,
+	// closed, all. Default is "open".
+	State string `url:"state,omitempty"`
+
+	// Labels filters issues based on their label.
+	Labels []string `url:"labels,comma,omitempty"`
+
+	// Sort specifies how to sort issues. Possible values are: created, updated,
+	// and comments. Default value is "created".
+	Sort string `url:"sort,omitempty"`
+
+	// Direction in which to sort issues. Possible values are: asc, desc.
+	// Default is "desc".
+	Direction string `url:"direction,omitempty"`
+
+	// Since filters issues by time.
+	Since time.Time `url:"since,omitempty"`
+
+	ListOptions
+}
+
+// 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"`
+}
+
+// List the issues for the authenticated user. If all is true, list issues
+// across all the user's visible repositories including owned, member, and
+// organization repositories; if false, list only owned and member
+// repositories.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/#list-issues
+func (s *IssuesService) List(ctx context.Context, all bool, opt *IssueListOptions) ([]*Issue, *Response, error) {
+	var u string
+	if all {
+		u = "issues"
+	} else {
+		u = "user/issues"
+	}
+	return s.listIssues(ctx, u, opt)
+}
+
+// ListByOrg fetches the issues in the specified organization for the
+// authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/#list-issues
+func (s *IssuesService) ListByOrg(ctx context.Context, org string, opt *IssueListOptions) ([]*Issue, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/issues", org)
+	return s.listIssues(ctx, u, opt)
+}
+
+func (s *IssuesService) listIssues(ctx context.Context, u string, opt *IssueListOptions) ([]*Issue, *Response, error) {
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	var issues []*Issue
+	resp, err := s.client.Do(ctx, req, &issues)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return issues, resp, nil
+}
+
+// IssueListByRepoOptions specifies the optional parameters to the
+// IssuesService.ListByRepo method.
+type IssueListByRepoOptions struct {
+	// Milestone limits issues for the specified milestone. Possible values are
+	// a milestone number, "none" for issues with no milestone, "*" for issues
+	// with any milestone.
+	Milestone string `url:"milestone,omitempty"`
+
+	// State filters issues based on their state. Possible values are: open,
+	// closed, all. Default is "open".
+	State string `url:"state,omitempty"`
+
+	// Assignee filters issues based on their assignee. Possible values are a
+	// user name, "none" for issues that are not assigned, "*" for issues with
+	// any assigned user.
+	Assignee string `url:"assignee,omitempty"`
+
+	// Creator filters issues based on their creator.
+	Creator string `url:"creator,omitempty"`
+
+	// Mentioned filters issues to those mentioned a specific user.
+	Mentioned string `url:"mentioned,omitempty"`
+
+	// Labels filters issues based on their label.
+	Labels []string `url:"labels,omitempty,comma"`
+
+	// Sort specifies how to sort issues. Possible values are: created, updated,
+	// and comments. Default value is "created".
+	Sort string `url:"sort,omitempty"`
+
+	// Direction in which to sort issues. Possible values are: asc, desc.
+	// Default is "desc".
+	Direction string `url:"direction,omitempty"`
+
+	// Since filters issues by time.
+	Since time.Time `url:"since,omitempty"`
+
+	ListOptions
+}
+
+// ListByRepo lists the issues for the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/#list-issues-for-a-repository
+func (s *IssuesService) ListByRepo(ctx context.Context, owner string, repo string, opt *IssueListByRepoOptions) ([]*Issue, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeIntegrationPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	var issues []*Issue
+	resp, err := s.client.Do(ctx, req, &issues)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return issues, resp, nil
+}
+
+// Get a single issue.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/#get-a-single-issue
+func (s *IssuesService) Get(ctx context.Context, owner string, repo string, number int) (*Issue, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%d", owner, repo, number)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	issue := new(Issue)
+	resp, err := s.client.Do(ctx, req, issue)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return issue, resp, nil
+}
+
+// Create a new issue on the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/#create-an-issue
+func (s *IssuesService) Create(ctx context.Context, owner string, repo string, issue *IssueRequest) (*Issue, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues", owner, repo)
+	req, err := s.client.NewRequest("POST", u, issue)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
+
+	i := new(Issue)
+	resp, err := s.client.Do(ctx, req, i)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return i, resp, nil
+}
+
+// Edit an issue.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/#edit-an-issue
+func (s *IssuesService) Edit(ctx context.Context, owner string, repo string, number int, issue *IssueRequest) (*Issue, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%d", owner, repo, number)
+	req, err := s.client.NewRequest("PATCH", u, issue)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
+
+	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 {
+	// LockReason specifies the reason to lock this issue.
+	// Providing a lock reason can help make it clearer to contributors why an issue
+	// was locked. Possible values are: "off-topic", "too heated", "resolved", and "spam".
+	LockReason string `json:"lock_reason,omitempty"`
+}
+
+// Lock an issue's conversation.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/#lock-an-issue
+func (s *IssuesService) Lock(ctx context.Context, owner string, repo string, number int, opt *LockIssueOptions) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%d/lock", owner, repo, number)
+	req, err := s.client.NewRequest("PUT", u, opt)
+	if err != nil {
+		return nil, err
+	}
+
+	if opt != nil {
+		req.Header.Set("Accept", mediaTypeLockReasonPreview)
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// Unlock an issue's conversation.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/#unlock-an-issue
+func (s *IssuesService) Unlock(ctx context.Context, owner string, repo string, number int) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%d/lock", owner, repo, number)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/issues_assignees.go b/vendor/github.com/google/go-github/v24/github/issues_assignees.go
new file mode 100644
index 000000000..9cb366f50
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/issues_assignees.go
@@ -0,0 +1,85 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// ListAssignees fetches all available assignees (owners and collaborators) to
+// which issues may be assigned.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/assignees/#list-assignees
+func (s *IssuesService) ListAssignees(ctx context.Context, owner, repo string, opt *ListOptions) ([]*User, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/assignees", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+	var assignees []*User
+	resp, err := s.client.Do(ctx, req, &assignees)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return assignees, resp, nil
+}
+
+// IsAssignee checks if a user is an assignee for the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/assignees/#check-assignee
+func (s *IssuesService) IsAssignee(ctx context.Context, owner, repo, user string) (bool, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/assignees/%v", owner, repo, user)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return false, nil, err
+	}
+	resp, err := s.client.Do(ctx, req, nil)
+	assignee, err := parseBoolResponse(err)
+	return assignee, resp, err
+}
+
+// AddAssignees adds the provided GitHub users as assignees to the issue.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/assignees/#add-assignees-to-an-issue
+func (s *IssuesService) AddAssignees(ctx context.Context, owner, repo string, number int, assignees []string) (*Issue, *Response, error) {
+	users := &struct {
+		Assignees []string `json:"assignees,omitempty"`
+	}{Assignees: assignees}
+	u := fmt.Sprintf("repos/%v/%v/issues/%v/assignees", owner, repo, number)
+	req, err := s.client.NewRequest("POST", u, users)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	issue := &Issue{}
+	resp, err := s.client.Do(ctx, req, issue)
+	return issue, resp, err
+}
+
+// RemoveAssignees removes the provided GitHub users as assignees from the issue.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/assignees/#remove-assignees-from-an-issue
+func (s *IssuesService) RemoveAssignees(ctx context.Context, owner, repo string, number int, assignees []string) (*Issue, *Response, error) {
+	users := &struct {
+		Assignees []string `json:"assignees,omitempty"`
+	}{Assignees: assignees}
+	u := fmt.Sprintf("repos/%v/%v/issues/%v/assignees", owner, repo, number)
+	req, err := s.client.NewRequest("DELETE", u, users)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	issue := &Issue{}
+	resp, err := s.client.Do(ctx, req, issue)
+	return issue, resp, err
+}
diff --git a/vendor/github.com/google/go-github/v24/github/issues_comments.go b/vendor/github.com/google/go-github/v24/github/issues_comments.go
new file mode 100644
index 000000000..ab68afe2f
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/issues_comments.go
@@ -0,0 +1,153 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// IssueComment represents a comment left on an issue.
+type IssueComment struct {
+	ID        *int64     `json:"id,omitempty"`
+	NodeID    *string    `json:"node_id,omitempty"`
+	Body      *string    `json:"body,omitempty"`
+	User      *User      `json:"user,omitempty"`
+	Reactions *Reactions `json:"reactions,omitempty"`
+	CreatedAt *time.Time `json:"created_at,omitempty"`
+	UpdatedAt *time.Time `json:"updated_at,omitempty"`
+	// AuthorAssociation is the comment author's relationship to the issue's repository.
+	// Possible values are "COLLABORATOR", "CONTRIBUTOR", "FIRST_TIMER", "FIRST_TIME_CONTRIBUTOR", "MEMBER", "OWNER", or "NONE".
+	AuthorAssociation *string `json:"author_association,omitempty"`
+	URL               *string `json:"url,omitempty"`
+	HTMLURL           *string `json:"html_url,omitempty"`
+	IssueURL          *string `json:"issue_url,omitempty"`
+}
+
+func (i IssueComment) String() string {
+	return Stringify(i)
+}
+
+// IssueListCommentsOptions specifies the optional parameters to the
+// IssuesService.ListComments method.
+type IssueListCommentsOptions struct {
+	// Sort specifies how to sort comments. Possible values are: created, updated.
+	Sort string `url:"sort,omitempty"`
+
+	// Direction in which to sort comments. Possible values are: asc, desc.
+	Direction string `url:"direction,omitempty"`
+
+	// Since filters comments by time.
+	Since time.Time `url:"since,omitempty"`
+
+	ListOptions
+}
+
+// ListComments lists all comments on the specified issue. Specifying an issue
+// number of 0 will return all comments on all issues for the repository.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/comments/#list-comments-on-an-issue
+func (s *IssuesService) ListComments(ctx context.Context, owner string, repo string, number int, opt *IssueListCommentsOptions) ([]*IssueComment, *Response, error) {
+	var u string
+	if number == 0 {
+		u = fmt.Sprintf("repos/%v/%v/issues/comments", owner, repo)
+	} else {
+		u = fmt.Sprintf("repos/%v/%v/issues/%d/comments", owner, repo, number)
+	}
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	var comments []*IssueComment
+	resp, err := s.client.Do(ctx, req, &comments)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return comments, resp, nil
+}
+
+// GetComment fetches the specified issue comment.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/comments/#get-a-single-comment
+func (s *IssuesService) GetComment(ctx context.Context, owner string, repo string, commentID int64) (*IssueComment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/comments/%d", owner, repo, commentID)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	comment := new(IssueComment)
+	resp, err := s.client.Do(ctx, req, comment)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return comment, resp, nil
+}
+
+// CreateComment creates a new comment on the specified issue.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/comments/#create-a-comment
+func (s *IssuesService) CreateComment(ctx context.Context, owner string, repo string, number int, comment *IssueComment) (*IssueComment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%d/comments", owner, repo, number)
+	req, err := s.client.NewRequest("POST", u, comment)
+	if err != nil {
+		return nil, nil, err
+	}
+	c := new(IssueComment)
+	resp, err := s.client.Do(ctx, req, c)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return c, resp, nil
+}
+
+// EditComment updates an issue comment.
+// A non-nil comment.Body must be provided. Other comment fields should be left nil.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/comments/#edit-a-comment
+func (s *IssuesService) EditComment(ctx context.Context, owner string, repo string, commentID int64, comment *IssueComment) (*IssueComment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/comments/%d", owner, repo, commentID)
+	req, err := s.client.NewRequest("PATCH", u, comment)
+	if err != nil {
+		return nil, nil, err
+	}
+	c := new(IssueComment)
+	resp, err := s.client.Do(ctx, req, c)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return c, resp, nil
+}
+
+// DeleteComment deletes an issue comment.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/comments/#delete-a-comment
+func (s *IssuesService) DeleteComment(ctx context.Context, owner string, repo string, commentID int64) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/comments/%d", owner, repo, commentID)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/issues_events.go b/vendor/github.com/google/go-github/v24/github/issues_events.go
new file mode 100644
index 000000000..6a43f1062
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/issues_events.go
@@ -0,0 +1,161 @@
+// Copyright 2014 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"strings"
+	"time"
+)
+
+// IssueEvent represents an event that occurred around an Issue or Pull Request.
+type IssueEvent struct {
+	ID  *int64  `json:"id,omitempty"`
+	URL *string `json:"url,omitempty"`
+
+	// The User that generated this event.
+	Actor *User `json:"actor,omitempty"`
+
+	// Event identifies the actual type of Event that occurred. Possible
+	// values are:
+	//
+	//     closed
+	//       The Actor closed the issue.
+	//       If the issue was closed by commit message, CommitID holds the SHA1 hash of the commit.
+	//
+	//     merged
+	//       The Actor merged into master a branch containing a commit mentioning the issue.
+	//       CommitID holds the SHA1 of the merge commit.
+	//
+	//     referenced
+	//       The Actor committed to master a commit mentioning the issue in its commit message.
+	//       CommitID holds the SHA1 of the commit.
+	//
+	//     reopened, unlocked
+	//       The Actor did that to the issue.
+	//
+	//     locked
+	//       The Actor locked the issue.
+	//       LockReason holds the reason of locking the issue (if provided while locking).
+	//
+	//     renamed
+	//       The Actor changed the issue title from Rename.From to Rename.To.
+	//
+	//     mentioned
+	//       Someone unspecified @mentioned the Actor [sic] in an issue comment body.
+	//
+	//     assigned, unassigned
+	//       The Assigner assigned the issue to or removed the assignment from the Assignee.
+	//
+	//     labeled, unlabeled
+	//       The Actor added or removed the Label from the issue.
+	//
+	//     milestoned, demilestoned
+	//       The Actor added or removed the issue from the Milestone.
+	//
+	//     subscribed, unsubscribed
+	//       The Actor subscribed to or unsubscribed from notifications for an issue.
+	//
+	//     head_ref_deleted, head_ref_restored
+	//       The pull request’s branch was deleted or restored.
+	//
+	Event *string `json:"event,omitempty"`
+
+	CreatedAt *time.Time `json:"created_at,omitempty"`
+	Issue     *Issue     `json:"issue,omitempty"`
+
+	// Only present on certain events; see above.
+	Assignee    *User        `json:"assignee,omitempty"`
+	Assigner    *User        `json:"assigner,omitempty"`
+	CommitID    *string      `json:"commit_id,omitempty"`
+	Milestone   *Milestone   `json:"milestone,omitempty"`
+	Label       *Label       `json:"label,omitempty"`
+	Rename      *Rename      `json:"rename,omitempty"`
+	LockReason  *string      `json:"lock_reason,omitempty"`
+	ProjectCard *ProjectCard `json:"project_card,omitempty"`
+}
+
+// ListIssueEvents lists events for the specified issue.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/events/#list-events-for-an-issue
+func (s *IssuesService) ListIssueEvents(ctx context.Context, owner, repo string, number int, opt *ListOptions) ([]*IssueEvent, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%v/events", owner, repo, number)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	acceptHeaders := []string{mediaTypeLockReasonPreview, mediaTypeProjectCardDetailsPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	var events []*IssueEvent
+	resp, err := s.client.Do(ctx, req, &events)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return events, resp, nil
+}
+
+// ListRepositoryEvents lists events for the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/events/#list-events-for-a-repository
+func (s *IssuesService) ListRepositoryEvents(ctx context.Context, owner, repo string, opt *ListOptions) ([]*IssueEvent, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/events", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var events []*IssueEvent
+	resp, err := s.client.Do(ctx, req, &events)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return events, resp, nil
+}
+
+// GetEvent returns the specified issue event.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/events/#get-a-single-event
+func (s *IssuesService) GetEvent(ctx context.Context, owner, repo string, id int64) (*IssueEvent, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/events/%v", owner, repo, id)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	event := new(IssueEvent)
+	resp, err := s.client.Do(ctx, req, event)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return event, resp, nil
+}
+
+// Rename contains details for 'renamed' events.
+type Rename struct {
+	From *string `json:"from,omitempty"`
+	To   *string `json:"to,omitempty"`
+}
+
+func (r Rename) String() string {
+	return Stringify(r)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/issues_labels.go b/vendor/github.com/google/go-github/v24/github/issues_labels.go
new file mode 100644
index 000000000..adcbe0683
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/issues_labels.go
@@ -0,0 +1,261 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// Label represents a GitHub label on an Issue
+type Label struct {
+	ID          *int64  `json:"id,omitempty"`
+	URL         *string `json:"url,omitempty"`
+	Name        *string `json:"name,omitempty"`
+	Color       *string `json:"color,omitempty"`
+	Description *string `json:"description,omitempty"`
+	Default     *bool   `json:"default,omitempty"`
+	NodeID      *string `json:"node_id,omitempty"`
+}
+
+func (l Label) String() string {
+	return Stringify(l)
+}
+
+// ListLabels lists all labels for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/labels/#list-all-labels-for-this-repository
+func (s *IssuesService) ListLabels(ctx context.Context, owner string, repo string, opt *ListOptions) ([]*Label, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/labels", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
+
+	var labels []*Label
+	resp, err := s.client.Do(ctx, req, &labels)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return labels, resp, nil
+}
+
+// GetLabel gets a single label.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/labels/#get-a-single-label
+func (s *IssuesService) GetLabel(ctx context.Context, owner string, repo string, name string) (*Label, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/labels/%v", owner, repo, name)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
+
+	label := new(Label)
+	resp, err := s.client.Do(ctx, req, label)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return label, resp, nil
+}
+
+// CreateLabel creates a new label on the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/labels/#create-a-label
+func (s *IssuesService) CreateLabel(ctx context.Context, owner string, repo string, label *Label) (*Label, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/labels", owner, repo)
+	req, err := s.client.NewRequest("POST", u, label)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
+
+	l := new(Label)
+	resp, err := s.client.Do(ctx, req, l)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return l, resp, nil
+}
+
+// EditLabel edits a label.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/labels/#update-a-label
+func (s *IssuesService) EditLabel(ctx context.Context, owner string, repo string, name string, label *Label) (*Label, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/labels/%v", owner, repo, name)
+	req, err := s.client.NewRequest("PATCH", u, label)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
+
+	l := new(Label)
+	resp, err := s.client.Do(ctx, req, l)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return l, resp, nil
+}
+
+// DeleteLabel deletes a label.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/labels/#delete-a-label
+func (s *IssuesService) DeleteLabel(ctx context.Context, owner string, repo string, name string) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/labels/%v", owner, repo, name)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
+
+// ListLabelsByIssue lists all labels for an issue.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/labels/#list-labels-on-an-issue
+func (s *IssuesService) ListLabelsByIssue(ctx context.Context, owner string, repo string, number int, opt *ListOptions) ([]*Label, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
+
+	var labels []*Label
+	resp, err := s.client.Do(ctx, req, &labels)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return labels, resp, nil
+}
+
+// AddLabelsToIssue adds labels to an issue.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/labels/#add-labels-to-an-issue
+func (s *IssuesService) AddLabelsToIssue(ctx context.Context, owner string, repo string, number int, labels []string) ([]*Label, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number)
+	req, err := s.client.NewRequest("POST", u, labels)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
+
+	var l []*Label
+	resp, err := s.client.Do(ctx, req, &l)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return l, resp, nil
+}
+
+// RemoveLabelForIssue removes a label for an issue.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/labels/#remove-a-label-from-an-issue
+func (s *IssuesService) RemoveLabelForIssue(ctx context.Context, owner string, repo string, number int, label string) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%d/labels/%v", owner, repo, number, label)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// ReplaceLabelsForIssue replaces all labels for an issue.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/labels/#replace-all-labels-for-an-issue
+func (s *IssuesService) ReplaceLabelsForIssue(ctx context.Context, owner string, repo string, number int, labels []string) ([]*Label, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number)
+	req, err := s.client.NewRequest("PUT", u, labels)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
+
+	var l []*Label
+	resp, err := s.client.Do(ctx, req, &l)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return l, resp, nil
+}
+
+// RemoveLabelsForIssue removes all labels for an issue.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/labels/#remove-all-labels-from-an-issue
+func (s *IssuesService) RemoveLabelsForIssue(ctx context.Context, owner string, repo string, number int) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// ListLabelsForMilestone lists labels for every issue in a milestone.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/labels/#get-labels-for-every-issue-in-a-milestone
+func (s *IssuesService) ListLabelsForMilestone(ctx context.Context, owner string, repo string, number int, opt *ListOptions) ([]*Label, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/milestones/%d/labels", owner, repo, number)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
+
+	var labels []*Label
+	resp, err := s.client.Do(ctx, req, &labels)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return labels, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/issues_milestones.go b/vendor/github.com/google/go-github/v24/github/issues_milestones.go
new file mode 100644
index 000000000..ffe9aae14
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/issues_milestones.go
@@ -0,0 +1,148 @@
+// Copyright 2014 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// Milestone represents a GitHub repository milestone.
+type Milestone struct {
+	URL          *string    `json:"url,omitempty"`
+	HTMLURL      *string    `json:"html_url,omitempty"`
+	LabelsURL    *string    `json:"labels_url,omitempty"`
+	ID           *int64     `json:"id,omitempty"`
+	Number       *int       `json:"number,omitempty"`
+	State        *string    `json:"state,omitempty"`
+	Title        *string    `json:"title,omitempty"`
+	Description  *string    `json:"description,omitempty"`
+	Creator      *User      `json:"creator,omitempty"`
+	OpenIssues   *int       `json:"open_issues,omitempty"`
+	ClosedIssues *int       `json:"closed_issues,omitempty"`
+	CreatedAt    *time.Time `json:"created_at,omitempty"`
+	UpdatedAt    *time.Time `json:"updated_at,omitempty"`
+	ClosedAt     *time.Time `json:"closed_at,omitempty"`
+	DueOn        *time.Time `json:"due_on,omitempty"`
+	NodeID       *string    `json:"node_id,omitempty"`
+}
+
+func (m Milestone) String() string {
+	return Stringify(m)
+}
+
+// MilestoneListOptions specifies the optional parameters to the
+// IssuesService.ListMilestones method.
+type MilestoneListOptions struct {
+	// State filters milestones based on their state. Possible values are:
+	// open, closed, all. Default is "open".
+	State string `url:"state,omitempty"`
+
+	// Sort specifies how to sort milestones. Possible values are: due_on, completeness.
+	// Default value is "due_on".
+	Sort string `url:"sort,omitempty"`
+
+	// Direction in which to sort milestones. Possible values are: asc, desc.
+	// Default is "asc".
+	Direction string `url:"direction,omitempty"`
+
+	ListOptions
+}
+
+// ListMilestones lists all milestones for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/milestones/#list-milestones-for-a-repository
+func (s *IssuesService) ListMilestones(ctx context.Context, owner string, repo string, opt *MilestoneListOptions) ([]*Milestone, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/milestones", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var milestones []*Milestone
+	resp, err := s.client.Do(ctx, req, &milestones)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return milestones, resp, nil
+}
+
+// GetMilestone gets a single milestone.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/milestones/#get-a-single-milestone
+func (s *IssuesService) GetMilestone(ctx context.Context, owner string, repo string, number int) (*Milestone, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/milestones/%d", owner, repo, number)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	milestone := new(Milestone)
+	resp, err := s.client.Do(ctx, req, milestone)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return milestone, resp, nil
+}
+
+// CreateMilestone creates a new milestone on the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/milestones/#create-a-milestone
+func (s *IssuesService) CreateMilestone(ctx context.Context, owner string, repo string, milestone *Milestone) (*Milestone, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/milestones", owner, repo)
+	req, err := s.client.NewRequest("POST", u, milestone)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	m := new(Milestone)
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// EditMilestone edits a milestone.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/milestones/#update-a-milestone
+func (s *IssuesService) EditMilestone(ctx context.Context, owner string, repo string, number int, milestone *Milestone) (*Milestone, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/milestones/%d", owner, repo, number)
+	req, err := s.client.NewRequest("PATCH", u, milestone)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	m := new(Milestone)
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// DeleteMilestone deletes a milestone.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/milestones/#delete-a-milestone
+func (s *IssuesService) DeleteMilestone(ctx context.Context, owner string, repo string, number int) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/milestones/%d", owner, repo, number)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/issues_timeline.go b/vendor/github.com/google/go-github/v24/github/issues_timeline.go
new file mode 100644
index 000000000..d0e4a3a94
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/issues_timeline.go
@@ -0,0 +1,154 @@
+// Copyright 2016 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"strings"
+	"time"
+)
+
+// Timeline represents an event that occurred around an Issue or Pull Request.
+//
+// It is similar to an IssueEvent but may contain more information.
+// GitHub API docs: https://developer.github.com/v3/issues/timeline/
+type Timeline struct {
+	ID        *int64  `json:"id,omitempty"`
+	URL       *string `json:"url,omitempty"`
+	CommitURL *string `json:"commit_url,omitempty"`
+
+	// The User object that generated the event.
+	Actor *User `json:"actor,omitempty"`
+
+	// Event identifies the actual type of Event that occurred. Possible values
+	// are:
+	//
+	//     assigned
+	//       The issue was assigned to the assignee.
+	//
+	//     closed
+	//       The issue was closed by the actor. When the commit_id is present, it
+	//       identifies the commit that closed the issue using "closes / fixes #NN"
+	//       syntax.
+	//
+	//     commented
+	//       A comment was added to the issue.
+	//
+	//     committed
+	//       A commit was added to the pull request's 'HEAD' branch. Only provided
+	//       for pull requests.
+	//
+	//     cross-referenced
+	//       The issue was referenced from another issue. The 'source' attribute
+	//       contains the 'id', 'actor', and 'url' of the reference's source.
+	//
+	//     demilestoned
+	//       The issue was removed from a milestone.
+	//
+	//     head_ref_deleted
+	//       The pull request's branch was deleted.
+	//
+	//     head_ref_restored
+	//       The pull request's branch was restored.
+	//
+	//     labeled
+	//       A label was added to the issue.
+	//
+	//     locked
+	//       The issue was locked by the actor.
+	//
+	//     mentioned
+	//       The actor was @mentioned in an issue body.
+	//
+	//     merged
+	//       The issue was merged by the actor. The 'commit_id' attribute is the
+	//       SHA1 of the HEAD commit that was merged.
+	//
+	//     milestoned
+	//       The issue was added to a milestone.
+	//
+	//     referenced
+	//       The issue was referenced from a commit message. The 'commit_id'
+	//       attribute is the commit SHA1 of where that happened.
+	//
+	//     renamed
+	//       The issue title was changed.
+	//
+	//     reopened
+	//       The issue was reopened by the actor.
+	//
+	//     subscribed
+	//       The actor subscribed to receive notifications for an issue.
+	//
+	//     unassigned
+	//       The assignee was unassigned from the issue.
+	//
+	//     unlabeled
+	//       A label was removed from the issue.
+	//
+	//     unlocked
+	//       The issue was unlocked by the actor.
+	//
+	//     unsubscribed
+	//       The actor unsubscribed to stop receiving notifications for an issue.
+	//
+	Event *string `json:"event,omitempty"`
+
+	// The string SHA of a commit that referenced this Issue or Pull Request.
+	CommitID *string `json:"commit_id,omitempty"`
+	// The timestamp indicating when the event occurred.
+	CreatedAt *time.Time `json:"created_at,omitempty"`
+	// The Label object including `name` and `color` attributes. Only provided for
+	// 'labeled' and 'unlabeled' events.
+	Label *Label `json:"label,omitempty"`
+	// The User object which was assigned to (or unassigned from) this Issue or
+	// Pull Request. Only provided for 'assigned' and 'unassigned' events.
+	Assignee *User `json:"assignee,omitempty"`
+	// The Milestone object including a 'title' attribute.
+	// Only provided for 'milestoned' and 'demilestoned' events.
+	Milestone *Milestone `json:"milestone,omitempty"`
+	// The 'id', 'actor', and 'url' for the source of a reference from another issue.
+	// Only provided for 'cross-referenced' events.
+	Source *Source `json:"source,omitempty"`
+	// An object containing rename details including 'from' and 'to' attributes.
+	// Only provided for 'renamed' events.
+	Rename      *Rename      `json:"rename,omitempty"`
+	ProjectCard *ProjectCard `json:"project_card,omitempty"`
+}
+
+// Source represents a reference's source.
+type Source struct {
+	ID    *int64  `json:"id,omitempty"`
+	URL   *string `json:"url,omitempty"`
+	Actor *User   `json:"actor,omitempty"`
+	Type  *string `json:"type,omitempty"`
+	Issue *Issue  `json:"issue,omitempty"`
+}
+
+// ListIssueTimeline lists events for the specified issue.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/timeline/#list-events-for-an-issue
+func (s *IssuesService) ListIssueTimeline(ctx context.Context, owner, repo string, number int, opt *ListOptions) ([]*Timeline, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%v/timeline", owner, repo, number)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	acceptHeaders := []string{mediaTypeTimelinePreview, mediaTypeProjectCardDetailsPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	var events []*Timeline
+	resp, err := s.client.Do(ctx, req, &events)
+	return events, resp, err
+}
diff --git a/vendor/github.com/google/go-github/v24/github/licenses.go b/vendor/github.com/google/go-github/v24/github/licenses.go
new file mode 100644
index 000000000..1176d3a8b
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/licenses.go
@@ -0,0 +1,97 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// LicensesService handles communication with the license related
+// methods of the GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/licenses/
+type LicensesService service
+
+// RepositoryLicense represents the license for a repository.
+type RepositoryLicense struct {
+	Name *string `json:"name,omitempty"`
+	Path *string `json:"path,omitempty"`
+
+	SHA         *string  `json:"sha,omitempty"`
+	Size        *int     `json:"size,omitempty"`
+	URL         *string  `json:"url,omitempty"`
+	HTMLURL     *string  `json:"html_url,omitempty"`
+	GitURL      *string  `json:"git_url,omitempty"`
+	DownloadURL *string  `json:"download_url,omitempty"`
+	Type        *string  `json:"type,omitempty"`
+	Content     *string  `json:"content,omitempty"`
+	Encoding    *string  `json:"encoding,omitempty"`
+	License     *License `json:"license,omitempty"`
+}
+
+func (l RepositoryLicense) String() string {
+	return Stringify(l)
+}
+
+// License represents an open source license.
+type License struct {
+	Key  *string `json:"key,omitempty"`
+	Name *string `json:"name,omitempty"`
+	URL  *string `json:"url,omitempty"`
+
+	SPDXID         *string   `json:"spdx_id,omitempty"`
+	HTMLURL        *string   `json:"html_url,omitempty"`
+	Featured       *bool     `json:"featured,omitempty"`
+	Description    *string   `json:"description,omitempty"`
+	Implementation *string   `json:"implementation,omitempty"`
+	Permissions    *[]string `json:"permissions,omitempty"`
+	Conditions     *[]string `json:"conditions,omitempty"`
+	Limitations    *[]string `json:"limitations,omitempty"`
+	Body           *string   `json:"body,omitempty"`
+}
+
+func (l License) String() string {
+	return Stringify(l)
+}
+
+// List popular open source licenses.
+//
+// GitHub API docs: https://developer.github.com/v3/licenses/#list-all-licenses
+func (s *LicensesService) List(ctx context.Context) ([]*License, *Response, error) {
+	req, err := s.client.NewRequest("GET", "licenses", nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var licenses []*License
+	resp, err := s.client.Do(ctx, req, &licenses)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return licenses, resp, nil
+}
+
+// Get extended metadata for one license.
+//
+// GitHub API docs: https://developer.github.com/v3/licenses/#get-an-individual-license
+func (s *LicensesService) Get(ctx context.Context, licenseName string) (*License, *Response, error) {
+	u := fmt.Sprintf("licenses/%s", licenseName)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	license := new(License)
+	resp, err := s.client.Do(ctx, req, license)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return license, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/messages.go b/vendor/github.com/google/go-github/v24/github/messages.go
new file mode 100644
index 000000000..75bc77051
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/messages.go
@@ -0,0 +1,248 @@
+// Copyright 2016 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file provides functions for validating payloads from GitHub Webhooks.
+// GitHub API docs: https://developer.github.com/webhooks/securing/#validating-payloads-from-github
+
+package github
+
+import (
+	"crypto/hmac"
+	"crypto/sha1"
+	"crypto/sha256"
+	"crypto/sha512"
+	"encoding/hex"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"hash"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+	"strings"
+)
+
+const (
+	// sha1Prefix is the prefix used by GitHub before the HMAC hexdigest.
+	sha1Prefix = "sha1"
+	// sha256Prefix and sha512Prefix are provided for future compatibility.
+	sha256Prefix = "sha256"
+	sha512Prefix = "sha512"
+	// signatureHeader is the GitHub header key used to pass the HMAC hexdigest.
+	signatureHeader = "X-Hub-Signature"
+	// eventTypeHeader is the GitHub header key used to pass the event type.
+	eventTypeHeader = "X-Github-Event"
+	// deliveryIDHeader is the GitHub header key used to pass the unique ID for the webhook event.
+	deliveryIDHeader = "X-Github-Delivery"
+)
+
+var (
+	// eventTypeMapping maps webhooks types to their corresponding go-github struct types.
+	eventTypeMapping = map[string]string{
+		"check_run":                      "CheckRunEvent",
+		"check_suite":                    "CheckSuiteEvent",
+		"commit_comment":                 "CommitCommentEvent",
+		"create":                         "CreateEvent",
+		"delete":                         "DeleteEvent",
+		"deployment":                     "DeploymentEvent",
+		"deployment_status":              "DeploymentStatusEvent",
+		"fork":                           "ForkEvent",
+		"gollum":                         "GollumEvent",
+		"installation":                   "InstallationEvent",
+		"installation_repositories":      "InstallationRepositoriesEvent",
+		"issue_comment":                  "IssueCommentEvent",
+		"issues":                         "IssuesEvent",
+		"label":                          "LabelEvent",
+		"marketplace_purchase":           "MarketplacePurchaseEvent",
+		"member":                         "MemberEvent",
+		"membership":                     "MembershipEvent",
+		"milestone":                      "MilestoneEvent",
+		"organization":                   "OrganizationEvent",
+		"org_block":                      "OrgBlockEvent",
+		"page_build":                     "PageBuildEvent",
+		"ping":                           "PingEvent",
+		"project":                        "ProjectEvent",
+		"project_card":                   "ProjectCardEvent",
+		"project_column":                 "ProjectColumnEvent",
+		"public":                         "PublicEvent",
+		"pull_request_review":            "PullRequestReviewEvent",
+		"pull_request_review_comment":    "PullRequestReviewCommentEvent",
+		"pull_request":                   "PullRequestEvent",
+		"push":                           "PushEvent",
+		"repository":                     "RepositoryEvent",
+		"repository_vulnerability_alert": "RepositoryVulnerabilityAlertEvent",
+		"release":                        "ReleaseEvent",
+		"status":                         "StatusEvent",
+		"team":                           "TeamEvent",
+		"team_add":                       "TeamAddEvent",
+		"watch":                          "WatchEvent",
+	}
+)
+
+// genMAC generates the HMAC signature for a message provided the secret key
+// and hashFunc.
+func genMAC(message, key []byte, hashFunc func() hash.Hash) []byte {
+	mac := hmac.New(hashFunc, key)
+	mac.Write(message)
+	return mac.Sum(nil)
+}
+
+// checkMAC reports whether messageMAC is a valid HMAC tag for message.
+func checkMAC(message, messageMAC, key []byte, hashFunc func() hash.Hash) bool {
+	expectedMAC := genMAC(message, key, hashFunc)
+	return hmac.Equal(messageMAC, expectedMAC)
+}
+
+// messageMAC returns the hex-decoded HMAC tag from the signature and its
+// corresponding hash function.
+func messageMAC(signature string) ([]byte, func() hash.Hash, error) {
+	if signature == "" {
+		return nil, nil, errors.New("missing signature")
+	}
+	sigParts := strings.SplitN(signature, "=", 2)
+	if len(sigParts) != 2 {
+		return nil, nil, fmt.Errorf("error parsing signature %q", signature)
+	}
+
+	var hashFunc func() hash.Hash
+	switch sigParts[0] {
+	case sha1Prefix:
+		hashFunc = sha1.New
+	case sha256Prefix:
+		hashFunc = sha256.New
+	case sha512Prefix:
+		hashFunc = sha512.New
+	default:
+		return nil, nil, fmt.Errorf("unknown hash type prefix: %q", sigParts[0])
+	}
+
+	buf, err := hex.DecodeString(sigParts[1])
+	if err != nil {
+		return nil, nil, fmt.Errorf("error decoding signature %q: %v", signature, err)
+	}
+	return buf, hashFunc, nil
+}
+
+// ValidatePayload validates an incoming GitHub Webhook event request
+// and returns the (JSON) payload.
+// The Content-Type header of the payload can be "application/json" or "application/x-www-form-urlencoded".
+// If the Content-Type is neither then an error is returned.
+// secretKey is the GitHub Webhook secret message.
+//
+// Example usage:
+//
+//     func (s *GitHubEventMonitor) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+//       payload, err := github.ValidatePayload(r, s.webhookSecretKey)
+//       if err != nil { ... }
+//       // Process payload...
+//     }
+//
+func ValidatePayload(r *http.Request, secretKey []byte) (payload []byte, err error) {
+	var body []byte // Raw body that GitHub uses to calculate the signature.
+
+	switch ct := r.Header.Get("Content-Type"); ct {
+	case "application/json":
+		var err error
+		if body, err = ioutil.ReadAll(r.Body); err != nil {
+			return nil, err
+		}
+
+		// If the content type is application/json,
+		// the JSON payload is just the original body.
+		payload = body
+
+	case "application/x-www-form-urlencoded":
+		// payloadFormParam is the name of the form parameter that the JSON payload
+		// will be in if a webhook has its content type set to application/x-www-form-urlencoded.
+		const payloadFormParam = "payload"
+
+		var err error
+		if body, err = ioutil.ReadAll(r.Body); err != nil {
+			return nil, err
+		}
+
+		// If the content type is application/x-www-form-urlencoded,
+		// the JSON payload will be under the "payload" form param.
+		form, err := url.ParseQuery(string(body))
+		if err != nil {
+			return nil, err
+		}
+		payload = []byte(form.Get(payloadFormParam))
+
+	default:
+		return nil, fmt.Errorf("Webhook request has unsupported Content-Type %q", ct)
+	}
+
+	sig := r.Header.Get(signatureHeader)
+	if err := ValidateSignature(sig, body, secretKey); err != nil {
+		return nil, err
+	}
+	return payload, nil
+}
+
+// ValidateSignature validates the signature for the given payload.
+// signature is the GitHub hash signature delivered in the X-Hub-Signature header.
+// payload is the JSON payload sent by GitHub Webhooks.
+// secretKey is the GitHub Webhook secret message.
+//
+// GitHub API docs: https://developer.github.com/webhooks/securing/#validating-payloads-from-github
+func ValidateSignature(signature string, payload, secretKey []byte) error {
+	messageMAC, hashFunc, err := messageMAC(signature)
+	if err != nil {
+		return err
+	}
+	if !checkMAC(payload, messageMAC, secretKey, hashFunc) {
+		return errors.New("payload signature check failed")
+	}
+	return nil
+}
+
+// WebHookType returns the event type of webhook request r.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/hooks/#webhook-headers
+func WebHookType(r *http.Request) string {
+	return r.Header.Get(eventTypeHeader)
+}
+
+// DeliveryID returns the unique delivery ID of webhook request r.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/hooks/#webhook-headers
+func DeliveryID(r *http.Request) string {
+	return r.Header.Get(deliveryIDHeader)
+}
+
+// ParseWebHook parses the event payload. For recognized event types, a
+// value of the corresponding struct type will be returned (as returned
+// by Event.ParsePayload()). An error will be returned for unrecognized event
+// types.
+//
+// Example usage:
+//
+//     func (s *GitHubEventMonitor) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+//       payload, err := github.ValidatePayload(r, s.webhookSecretKey)
+//       if err != nil { ... }
+//       event, err := github.ParseWebHook(github.WebHookType(r), payload)
+//       if err != nil { ... }
+//       switch event := event.(type) {
+//       case *github.CommitCommentEvent:
+//           processCommitCommentEvent(event)
+//       case *github.CreateEvent:
+//           processCreateEvent(event)
+//       ...
+//       }
+//     }
+//
+func ParseWebHook(messageType string, payload []byte) (interface{}, error) {
+	eventType, ok := eventTypeMapping[messageType]
+	if !ok {
+		return nil, fmt.Errorf("unknown X-Github-Event in message: %v", messageType)
+	}
+
+	event := Event{
+		Type:       &eventType,
+		RawPayload: (*json.RawMessage)(&payload),
+	}
+	return event.ParsePayload()
+}
diff --git a/vendor/github.com/google/go-github/v24/github/migrations.go b/vendor/github.com/google/go-github/v24/github/migrations.go
new file mode 100644
index 000000000..90cc1fae8
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/migrations.go
@@ -0,0 +1,224 @@
+// Copyright 2016 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"net/http"
+	"strings"
+)
+
+// MigrationService provides access to the migration related functions
+// in the GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/
+type MigrationService service
+
+// Migration represents a GitHub migration (archival).
+type Migration struct {
+	ID   *int64  `json:"id,omitempty"`
+	GUID *string `json:"guid,omitempty"`
+	// State is the current state of a migration.
+	// Possible values are:
+	//     "pending" which means the migration hasn't started yet,
+	//     "exporting" which means the migration is in progress,
+	//     "exported" which means the migration finished successfully, or
+	//     "failed" which means the migration failed.
+	State *string `json:"state,omitempty"`
+	// LockRepositories indicates whether repositories are locked (to prevent
+	// manipulation) while migrating data.
+	LockRepositories *bool `json:"lock_repositories,omitempty"`
+	// ExcludeAttachments indicates whether attachments should be excluded from
+	// the migration (to reduce migration archive file size).
+	ExcludeAttachments *bool         `json:"exclude_attachments,omitempty"`
+	URL                *string       `json:"url,omitempty"`
+	CreatedAt          *string       `json:"created_at,omitempty"`
+	UpdatedAt          *string       `json:"updated_at,omitempty"`
+	Repositories       []*Repository `json:"repositories,omitempty"`
+}
+
+func (m Migration) String() string {
+	return Stringify(m)
+}
+
+// MigrationOptions specifies the optional parameters to Migration methods.
+type MigrationOptions struct {
+	// LockRepositories indicates whether repositories should be locked (to prevent
+	// manipulation) while migrating data.
+	LockRepositories bool
+
+	// ExcludeAttachments indicates whether attachments should be excluded from
+	// the migration (to reduce migration archive file size).
+	ExcludeAttachments bool
+}
+
+// startMigration represents the body of a StartMigration request.
+type startMigration struct {
+	// Repositories is a slice of repository names to migrate.
+	Repositories []string `json:"repositories,omitempty"`
+
+	// LockRepositories indicates whether repositories should be locked (to prevent
+	// manipulation) while migrating data.
+	LockRepositories *bool `json:"lock_repositories,omitempty"`
+
+	// ExcludeAttachments indicates whether attachments should be excluded from
+	// the migration (to reduce migration archive file size).
+	ExcludeAttachments *bool `json:"exclude_attachments,omitempty"`
+}
+
+// StartMigration starts the generation of a migration archive.
+// repos is a slice of repository names to migrate.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/migrations/#start-a-migration
+func (s *MigrationService) StartMigration(ctx context.Context, org string, repos []string, opt *MigrationOptions) (*Migration, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/migrations", org)
+
+	body := &startMigration{Repositories: repos}
+	if opt != nil {
+		body.LockRepositories = Bool(opt.LockRepositories)
+		body.ExcludeAttachments = Bool(opt.ExcludeAttachments)
+	}
+
+	req, err := s.client.NewRequest("POST", u, body)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeMigrationsPreview)
+
+	m := &Migration{}
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// ListMigrations lists the most recent migrations.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/migrations/#get-a-list-of-migrations
+func (s *MigrationService) ListMigrations(ctx context.Context, org string) ([]*Migration, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/migrations", org)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeMigrationsPreview)
+
+	var m []*Migration
+	resp, err := s.client.Do(ctx, req, &m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// MigrationStatus gets the status of a specific migration archive.
+// id is the migration ID.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/migrations/#get-the-status-of-a-migration
+func (s *MigrationService) MigrationStatus(ctx context.Context, org string, id int64) (*Migration, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/migrations/%v", org, id)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeMigrationsPreview)
+
+	m := &Migration{}
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// MigrationArchiveURL fetches a migration archive URL.
+// id is the migration ID.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/migrations/#download-a-migration-archive
+func (s *MigrationService) MigrationArchiveURL(ctx context.Context, org string, id int64) (url string, err error) {
+	u := fmt.Sprintf("orgs/%v/migrations/%v/archive", org, id)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return "", err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeMigrationsPreview)
+
+	s.client.clientMu.Lock()
+	defer s.client.clientMu.Unlock()
+
+	// Disable the redirect mechanism because AWS fails if the GitHub auth token is provided.
+	var loc string
+	saveRedirect := s.client.client.CheckRedirect
+	s.client.client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
+		loc = req.URL.String()
+		return errors.New("disable redirect")
+	}
+	defer func() { s.client.client.CheckRedirect = saveRedirect }()
+
+	_, err = s.client.Do(ctx, req, nil) // expect error from disable redirect
+	if err == nil {
+		return "", errors.New("expected redirect, none provided")
+	}
+	if !strings.Contains(err.Error(), "disable redirect") {
+		return "", err
+	}
+	return loc, nil
+}
+
+// DeleteMigration deletes a previous migration archive.
+// id is the migration ID.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/migrations/#delete-a-migration-archive
+func (s *MigrationService) DeleteMigration(ctx context.Context, org string, id int64) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/migrations/%v/archive", org, id)
+
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeMigrationsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// UnlockRepo unlocks a repository that was locked for migration.
+// id is the migration ID.
+// You should unlock each migrated repository and delete them when the migration
+// is complete and you no longer need the source data.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/migrations/#unlock-a-repository
+func (s *MigrationService) UnlockRepo(ctx context.Context, org string, id int64, repo string) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/migrations/%v/repos/%v/lock", org, id, repo)
+
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeMigrationsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/migrations_source_import.go b/vendor/github.com/google/go-github/v24/github/migrations_source_import.go
new file mode 100644
index 000000000..fd45e7800
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/migrations_source_import.go
@@ -0,0 +1,329 @@
+// Copyright 2016 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// Import represents a repository import request.
+type Import struct {
+	// The URL of the originating repository.
+	VCSURL *string `json:"vcs_url,omitempty"`
+	// The originating VCS type. Can be one of 'subversion', 'git',
+	// 'mercurial', or 'tfvc'. Without this parameter, the import job will
+	// take additional time to detect the VCS type before beginning the
+	// import. This detection step will be reflected in the response.
+	VCS *string `json:"vcs,omitempty"`
+	// VCSUsername and VCSPassword are only used for StartImport calls that
+	// are importing a password-protected repository.
+	VCSUsername *string `json:"vcs_username,omitempty"`
+	VCSPassword *string `json:"vcs_password,omitempty"`
+	// For a tfvc import, the name of the project that is being imported.
+	TFVCProject *string `json:"tfvc_project,omitempty"`
+
+	// LFS related fields that may be preset in the Import Progress response
+
+	// Describes whether the import has been opted in or out of using Git
+	// LFS. The value can be 'opt_in', 'opt_out', or 'undecided' if no
+	// action has been taken.
+	UseLFS *string `json:"use_lfs,omitempty"`
+	// Describes whether files larger than 100MB were found during the
+	// importing step.
+	HasLargeFiles *bool `json:"has_large_files,omitempty"`
+	// The total size in gigabytes of files larger than 100MB found in the
+	// originating repository.
+	LargeFilesSize *int `json:"large_files_size,omitempty"`
+	// The total number of files larger than 100MB found in the originating
+	// repository. To see a list of these files, call LargeFiles.
+	LargeFilesCount *int `json:"large_files_count,omitempty"`
+
+	// Identifies the current status of an import. An import that does not
+	// have errors will progress through these steps:
+	//
+	//     detecting - the "detection" step of the import is in progress
+	//         because the request did not include a VCS parameter. The
+	//         import is identifying the type of source control present at
+	//         the URL.
+	//     importing - the "raw" step of the import is in progress. This is
+	//         where commit data is fetched from the original repository.
+	//         The import progress response will include CommitCount (the
+	//         total number of raw commits that will be imported) and
+	//         Percent (0 - 100, the current progress through the import).
+	//     mapping - the "rewrite" step of the import is in progress. This
+	//         is where SVN branches are converted to Git branches, and
+	//         where author updates are applied. The import progress
+	//         response does not include progress information.
+	//     pushing - the "push" step of the import is in progress. This is
+	//         where the importer updates the repository on GitHub. The
+	//         import progress response will include PushPercent, which is
+	//         the percent value reported by git push when it is "Writing
+	//         objects".
+	//     complete - the import is complete, and the repository is ready
+	//         on GitHub.
+	//
+	// If there are problems, you will see one of these in the status field:
+	//
+	//     auth_failed - the import requires authentication in order to
+	//         connect to the original repository. Make an UpdateImport
+	//         request, and include VCSUsername and VCSPassword.
+	//     error - the import encountered an error. The import progress
+	//         response will include the FailedStep and an error message.
+	//         Contact GitHub support for more information.
+	//     detection_needs_auth - the importer requires authentication for
+	//         the originating repository to continue detection. Make an
+	//         UpdatImport request, and include VCSUsername and
+	//         VCSPassword.
+	//     detection_found_nothing - the importer didn't recognize any
+	//         source control at the URL.
+	//     detection_found_multiple - the importer found several projects
+	//         or repositories at the provided URL. When this is the case,
+	//         the Import Progress response will also include a
+	//         ProjectChoices field with the possible project choices as
+	//         values. Make an UpdateImport request, and include VCS and
+	//         (if applicable) TFVCProject.
+	Status        *string `json:"status,omitempty"`
+	CommitCount   *int    `json:"commit_count,omitempty"`
+	StatusText    *string `json:"status_text,omitempty"`
+	AuthorsCount  *int    `json:"authors_count,omitempty"`
+	Percent       *int    `json:"percent,omitempty"`
+	PushPercent   *int    `json:"push_percent,omitempty"`
+	URL           *string `json:"url,omitempty"`
+	HTMLURL       *string `json:"html_url,omitempty"`
+	AuthorsURL    *string `json:"authors_url,omitempty"`
+	RepositoryURL *string `json:"repository_url,omitempty"`
+	Message       *string `json:"message,omitempty"`
+	FailedStep    *string `json:"failed_step,omitempty"`
+
+	// Human readable display name, provided when the Import appears as
+	// part of ProjectChoices.
+	HumanName *string `json:"human_name,omitempty"`
+
+	// When the importer finds several projects or repositories at the
+	// provided URLs, this will identify the available choices. Call
+	// UpdateImport with the selected Import value.
+	ProjectChoices []Import `json:"project_choices,omitempty"`
+}
+
+func (i Import) String() string {
+	return Stringify(i)
+}
+
+// SourceImportAuthor identifies an author imported from a source repository.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#get-commit-authors
+type SourceImportAuthor struct {
+	ID         *int64  `json:"id,omitempty"`
+	RemoteID   *string `json:"remote_id,omitempty"`
+	RemoteName *string `json:"remote_name,omitempty"`
+	Email      *string `json:"email,omitempty"`
+	Name       *string `json:"name,omitempty"`
+	URL        *string `json:"url,omitempty"`
+	ImportURL  *string `json:"import_url,omitempty"`
+}
+
+func (a SourceImportAuthor) String() string {
+	return Stringify(a)
+}
+
+// LargeFile identifies a file larger than 100MB found during a repository import.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#get-large-files
+type LargeFile struct {
+	RefName *string `json:"ref_name,omitempty"`
+	Path    *string `json:"path,omitempty"`
+	OID     *string `json:"oid,omitempty"`
+	Size    *int    `json:"size,omitempty"`
+}
+
+func (f LargeFile) String() string {
+	return Stringify(f)
+}
+
+// StartImport initiates a repository import.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#start-an-import
+func (s *MigrationService) StartImport(ctx context.Context, owner, repo string, in *Import) (*Import, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/import", owner, repo)
+	req, err := s.client.NewRequest("PUT", u, in)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeImportPreview)
+
+	out := new(Import)
+	resp, err := s.client.Do(ctx, req, out)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return out, resp, nil
+}
+
+// ImportProgress queries for the status and progress of an ongoing repository import.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#get-import-progress
+func (s *MigrationService) ImportProgress(ctx context.Context, owner, repo string) (*Import, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/import", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeImportPreview)
+
+	out := new(Import)
+	resp, err := s.client.Do(ctx, req, out)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return out, resp, nil
+}
+
+// UpdateImport initiates a repository import.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#update-existing-import
+func (s *MigrationService) UpdateImport(ctx context.Context, owner, repo string, in *Import) (*Import, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/import", owner, repo)
+	req, err := s.client.NewRequest("PATCH", u, in)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeImportPreview)
+
+	out := new(Import)
+	resp, err := s.client.Do(ctx, req, out)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return out, resp, nil
+}
+
+// CommitAuthors gets the authors mapped from the original repository.
+//
+// Each type of source control system represents authors in a different way.
+// For example, a Git commit author has a display name and an email address,
+// but a Subversion commit author just has a username. The GitHub Importer will
+// make the author information valid, but the author might not be correct. For
+// example, it will change the bare Subversion username "hubot" into something
+// like "hubot <hubot@12341234-abab-fefe-8787-fedcba987654>".
+//
+// This method and MapCommitAuthor allow you to provide correct Git author
+// information.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#get-commit-authors
+func (s *MigrationService) CommitAuthors(ctx context.Context, owner, repo string) ([]*SourceImportAuthor, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/import/authors", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeImportPreview)
+
+	var authors []*SourceImportAuthor
+	resp, err := s.client.Do(ctx, req, &authors)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return authors, resp, nil
+}
+
+// MapCommitAuthor updates an author's identity for the import. Your
+// application can continue updating authors any time before you push new
+// commits to the repository.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#map-a-commit-author
+func (s *MigrationService) MapCommitAuthor(ctx context.Context, owner, repo string, id int64, author *SourceImportAuthor) (*SourceImportAuthor, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/import/authors/%v", owner, repo, id)
+	req, err := s.client.NewRequest("PATCH", u, author)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeImportPreview)
+
+	out := new(SourceImportAuthor)
+	resp, err := s.client.Do(ctx, req, out)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return out, resp, nil
+}
+
+// SetLFSPreference sets whether imported repositories should use Git LFS for
+// files larger than 100MB. Only the UseLFS field on the provided Import is
+// used.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#set-git-lfs-preference
+func (s *MigrationService) SetLFSPreference(ctx context.Context, owner, repo string, in *Import) (*Import, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/import/lfs", owner, repo)
+	req, err := s.client.NewRequest("PATCH", u, in)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeImportPreview)
+
+	out := new(Import)
+	resp, err := s.client.Do(ctx, req, out)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return out, resp, nil
+}
+
+// LargeFiles lists files larger than 100MB found during the import.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#get-large-files
+func (s *MigrationService) LargeFiles(ctx context.Context, owner, repo string) ([]*LargeFile, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/import/large_files", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeImportPreview)
+
+	var files []*LargeFile
+	resp, err := s.client.Do(ctx, req, &files)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return files, resp, nil
+}
+
+// CancelImport stops an import for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#cancel-an-import
+func (s *MigrationService) CancelImport(ctx context.Context, owner, repo string) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/import", owner, repo)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeImportPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/migrations_user.go b/vendor/github.com/google/go-github/v24/github/migrations_user.go
new file mode 100644
index 000000000..d45555f21
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/migrations_user.go
@@ -0,0 +1,214 @@
+// Copyright 2018 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"net/http"
+)
+
+// UserMigration represents a GitHub migration (archival).
+type UserMigration struct {
+	ID   *int64  `json:"id,omitempty"`
+	GUID *string `json:"guid,omitempty"`
+	// State is the current state of a migration.
+	// Possible values are:
+	//     "pending" which means the migration hasn't started yet,
+	//     "exporting" which means the migration is in progress,
+	//     "exported" which means the migration finished successfully, or
+	//     "failed" which means the migration failed.
+	State *string `json:"state,omitempty"`
+	// LockRepositories indicates whether repositories are locked (to prevent
+	// manipulation) while migrating data.
+	LockRepositories *bool `json:"lock_repositories,omitempty"`
+	// ExcludeAttachments indicates whether attachments should be excluded from
+	// the migration (to reduce migration archive file size).
+	ExcludeAttachments *bool         `json:"exclude_attachments,omitempty"`
+	URL                *string       `json:"url,omitempty"`
+	CreatedAt          *string       `json:"created_at,omitempty"`
+	UpdatedAt          *string       `json:"updated_at,omitempty"`
+	Repositories       []*Repository `json:"repositories,omitempty"`
+}
+
+func (m UserMigration) String() string {
+	return Stringify(m)
+}
+
+// UserMigrationOptions specifies the optional parameters to Migration methods.
+type UserMigrationOptions struct {
+	// LockRepositories indicates whether repositories should be locked (to prevent
+	// manipulation) while migrating data.
+	LockRepositories bool
+
+	// ExcludeAttachments indicates whether attachments should be excluded from
+	// the migration (to reduce migration archive file size).
+	ExcludeAttachments bool
+}
+
+// startUserMigration represents the body of a StartMigration request.
+type startUserMigration struct {
+	// Repositories is a slice of repository names to migrate.
+	Repositories []string `json:"repositories,omitempty"`
+
+	// LockRepositories indicates whether repositories should be locked (to prevent
+	// manipulation) while migrating data.
+	LockRepositories *bool `json:"lock_repositories,omitempty"`
+
+	// ExcludeAttachments indicates whether attachments should be excluded from
+	// the migration (to reduce migration archive file size).
+	ExcludeAttachments *bool `json:"exclude_attachments,omitempty"`
+}
+
+// StartUserMigration starts the generation of a migration archive.
+// repos is a slice of repository names to migrate.
+//
+// GitHub API docs: https://developer.github.com/v3/migrations/users/#start-a-user-migration
+func (s *MigrationService) StartUserMigration(ctx context.Context, repos []string, opt *UserMigrationOptions) (*UserMigration, *Response, error) {
+	u := "user/migrations"
+
+	body := &startUserMigration{Repositories: repos}
+	if opt != nil {
+		body.LockRepositories = Bool(opt.LockRepositories)
+		body.ExcludeAttachments = Bool(opt.ExcludeAttachments)
+	}
+
+	req, err := s.client.NewRequest("POST", u, body)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeMigrationsPreview)
+
+	m := &UserMigration{}
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// ListUserMigrations lists the most recent migrations.
+//
+// GitHub API docs: https://developer.github.com/v3/migrations/users/#get-a-list-of-user-migrations
+func (s *MigrationService) ListUserMigrations(ctx context.Context) ([]*UserMigration, *Response, error) {
+	u := "user/migrations"
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeMigrationsPreview)
+
+	var m []*UserMigration
+	resp, err := s.client.Do(ctx, req, &m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// UserMigrationStatus gets the status of a specific migration archive.
+// id is the migration ID.
+//
+// GitHub API docs: https://developer.github.com/v3/migrations/users/#get-the-status-of-a-user-migration
+func (s *MigrationService) UserMigrationStatus(ctx context.Context, id int64) (*UserMigration, *Response, error) {
+	u := fmt.Sprintf("user/migrations/%v", id)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeMigrationsPreview)
+
+	m := &UserMigration{}
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// UserMigrationArchiveURL gets the URL for a specific migration archive.
+// id is the migration ID.
+//
+// GitHub API docs: https://developer.github.com/v3/migrations/users/#download-a-user-migration-archive
+func (s *MigrationService) UserMigrationArchiveURL(ctx context.Context, id int64) (string, error) {
+	url := fmt.Sprintf("user/migrations/%v/archive", id)
+
+	req, err := s.client.NewRequest("GET", url, nil)
+	if err != nil {
+		return "", err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeMigrationsPreview)
+
+	m := &UserMigration{}
+
+	var loc string
+	originalRedirect := s.client.client.CheckRedirect
+	s.client.client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
+		loc = req.URL.String()
+		return http.ErrUseLastResponse
+	}
+	defer func() {
+		s.client.client.CheckRedirect = originalRedirect
+	}()
+	resp, err := s.client.Do(ctx, req, m)
+	if err == nil {
+		return "", errors.New("expected redirect, none provided")
+	}
+	loc = resp.Header.Get("Location")
+	return loc, nil
+}
+
+// DeleteUserMigration will delete a previous migration archive.
+// id is the migration ID.
+//
+// GitHub API docs: https://developer.github.com/v3/migrations/users/#delete-a-user-migration-archive
+func (s *MigrationService) DeleteUserMigration(ctx context.Context, id int64) (*Response, error) {
+	url := fmt.Sprintf("user/migrations/%v/archive", id)
+
+	req, err := s.client.NewRequest("DELETE", url, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeMigrationsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// UnlockUserRepo will unlock a repo that was locked for migration.
+// id is migration ID.
+// You should unlock each migrated repository and delete them when the migration
+// is complete and you no longer need the source data.
+//
+// GitHub API docs: https://developer.github.com/v3/migrations/users/#unlock-a-user-repository
+func (s *MigrationService) UnlockUserRepo(ctx context.Context, id int64, repo string) (*Response, error) {
+	url := fmt.Sprintf("user/migrations/%v/repos/%v/lock", id, repo)
+
+	req, err := s.client.NewRequest("DELETE", url, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeMigrationsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/misc.go b/vendor/github.com/google/go-github/v24/github/misc.go
new file mode 100644
index 000000000..e9b0ea22a
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/misc.go
@@ -0,0 +1,257 @@
+// Copyright 2014 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"net/url"
+)
+
+// MarkdownOptions specifies optional parameters to the Markdown method.
+type MarkdownOptions struct {
+	// Mode identifies the rendering mode. Possible values are:
+	//   markdown - render a document as plain Markdown, just like
+	//   README files are rendered.
+	//
+	//   gfm - to render a document as user-content, e.g. like user
+	//   comments or issues are rendered. In GFM mode, hard line breaks are
+	//   always taken into account, and issue and user mentions are linked
+	//   accordingly.
+	//
+	// Default is "markdown".
+	Mode string
+
+	// Context identifies the repository context. Only taken into account
+	// when rendering as "gfm".
+	Context string
+}
+
+type markdownRequest struct {
+	Text    *string `json:"text,omitempty"`
+	Mode    *string `json:"mode,omitempty"`
+	Context *string `json:"context,omitempty"`
+}
+
+// Markdown renders an arbitrary Markdown document.
+//
+// GitHub API docs: https://developer.github.com/v3/markdown/
+func (c *Client) Markdown(ctx context.Context, text string, opt *MarkdownOptions) (string, *Response, error) {
+	request := &markdownRequest{Text: String(text)}
+	if opt != nil {
+		if opt.Mode != "" {
+			request.Mode = String(opt.Mode)
+		}
+		if opt.Context != "" {
+			request.Context = String(opt.Context)
+		}
+	}
+
+	req, err := c.NewRequest("POST", "markdown", request)
+	if err != nil {
+		return "", nil, err
+	}
+
+	buf := new(bytes.Buffer)
+	resp, err := c.Do(ctx, req, buf)
+	if err != nil {
+		return "", resp, err
+	}
+
+	return buf.String(), resp, nil
+}
+
+// ListEmojis returns the emojis available to use on GitHub.
+//
+// GitHub API docs: https://developer.github.com/v3/emojis/
+func (c *Client) ListEmojis(ctx context.Context) (map[string]string, *Response, error) {
+	req, err := c.NewRequest("GET", "emojis", nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var emoji map[string]string
+	resp, err := c.Do(ctx, req, &emoji)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return emoji, resp, nil
+}
+
+// CodeOfConduct represents a code of conduct.
+type CodeOfConduct struct {
+	Name *string `json:"name,omitempty"`
+	Key  *string `json:"key,omitempty"`
+	URL  *string `json:"url,omitempty"`
+	Body *string `json:"body,omitempty"`
+}
+
+func (c *CodeOfConduct) String() string {
+	return Stringify(c)
+}
+
+// ListCodesOfConduct returns all codes of conduct.
+//
+// GitHub API docs: https://developer.github.com/v3/codes_of_conduct/#list-all-codes-of-conduct
+func (c *Client) ListCodesOfConduct(ctx context.Context) ([]*CodeOfConduct, *Response, error) {
+	req, err := c.NewRequest("GET", "codes_of_conduct", nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeCodesOfConductPreview)
+
+	var cs []*CodeOfConduct
+	resp, err := c.Do(ctx, req, &cs)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return cs, resp, nil
+}
+
+// GetCodeOfConduct returns an individual code of conduct.
+//
+// https://developer.github.com/v3/codes_of_conduct/#get-an-individual-code-of-conduct
+func (c *Client) GetCodeOfConduct(ctx context.Context, key string) (*CodeOfConduct, *Response, error) {
+	u := fmt.Sprintf("codes_of_conduct/%s", key)
+	req, err := c.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeCodesOfConductPreview)
+
+	coc := new(CodeOfConduct)
+	resp, err := c.Do(ctx, req, coc)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return coc, resp, nil
+}
+
+// APIMeta represents metadata about the GitHub API.
+type APIMeta struct {
+	// An Array of IP addresses in CIDR format specifying the addresses
+	// that incoming service hooks will originate from on GitHub.com.
+	Hooks []string `json:"hooks,omitempty"`
+
+	// An Array of IP addresses in CIDR format specifying the Git servers
+	// for GitHub.com.
+	Git []string `json:"git,omitempty"`
+
+	// Whether authentication with username and password is supported.
+	// (GitHub Enterprise instances using CAS or OAuth for authentication
+	// will return false. Features like Basic Authentication with a
+	// username and password, sudo mode, and two-factor authentication are
+	// not supported on these servers.)
+	VerifiablePasswordAuthentication *bool `json:"verifiable_password_authentication,omitempty"`
+
+	// An array of IP addresses in CIDR format specifying the addresses
+	// which serve GitHub Pages websites.
+	Pages []string `json:"pages,omitempty"`
+
+	// An Array of IP addresses specifying the addresses that source imports
+	// will originate from on GitHub.com.
+	Importer []string `json:"importer,omitempty"`
+}
+
+// APIMeta returns information about GitHub.com, the service. Or, if you access
+// this endpoint on your organization’s GitHub Enterprise installation, this
+// endpoint provides information about that installation.
+//
+// GitHub API docs: https://developer.github.com/v3/meta/
+func (c *Client) APIMeta(ctx context.Context) (*APIMeta, *Response, error) {
+	req, err := c.NewRequest("GET", "meta", nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	meta := new(APIMeta)
+	resp, err := c.Do(ctx, req, meta)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return meta, resp, nil
+}
+
+// Octocat returns an ASCII art octocat with the specified message in a speech
+// bubble. If message is empty, a random zen phrase is used.
+func (c *Client) Octocat(ctx context.Context, message string) (string, *Response, error) {
+	u := "octocat"
+	if message != "" {
+		u = fmt.Sprintf("%s?s=%s", u, url.QueryEscape(message))
+	}
+
+	req, err := c.NewRequest("GET", u, nil)
+	if err != nil {
+		return "", nil, err
+	}
+
+	buf := new(bytes.Buffer)
+	resp, err := c.Do(ctx, req, buf)
+	if err != nil {
+		return "", resp, err
+	}
+
+	return buf.String(), resp, nil
+}
+
+// Zen returns a random line from The Zen of GitHub.
+//
+// see also: http://warpspire.com/posts/taste/
+func (c *Client) Zen(ctx context.Context) (string, *Response, error) {
+	req, err := c.NewRequest("GET", "zen", nil)
+	if err != nil {
+		return "", nil, err
+	}
+
+	buf := new(bytes.Buffer)
+	resp, err := c.Do(ctx, req, buf)
+	if err != nil {
+		return "", resp, err
+	}
+
+	return buf.String(), resp, nil
+}
+
+// ServiceHook represents a hook that has configuration settings, a list of
+// available events, and default events.
+type ServiceHook struct {
+	Name            *string    `json:"name,omitempty"`
+	Events          []string   `json:"events,omitempty"`
+	SupportedEvents []string   `json:"supported_events,omitempty"`
+	Schema          [][]string `json:"schema,omitempty"`
+}
+
+func (s *ServiceHook) String() string {
+	return Stringify(s)
+}
+
+// ListServiceHooks lists all of the available service hooks.
+//
+// GitHub API docs: https://developer.github.com/webhooks/#services
+func (c *Client) ListServiceHooks(ctx context.Context) ([]*ServiceHook, *Response, error) {
+	u := "hooks"
+	req, err := c.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var hooks []*ServiceHook
+	resp, err := c.Do(ctx, req, &hooks)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return hooks, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/orgs.go b/vendor/github.com/google/go-github/v24/github/orgs.go
new file mode 100644
index 000000000..c70039ba0
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/orgs.go
@@ -0,0 +1,208 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// OrganizationsService provides access to the organization related functions
+// in the GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/
+type OrganizationsService service
+
+// Organization represents a GitHub organization account.
+type Organization struct {
+	Login                       *string    `json:"login,omitempty"`
+	ID                          *int64     `json:"id,omitempty"`
+	NodeID                      *string    `json:"node_id,omitempty"`
+	AvatarURL                   *string    `json:"avatar_url,omitempty"`
+	HTMLURL                     *string    `json:"html_url,omitempty"`
+	Name                        *string    `json:"name,omitempty"`
+	Company                     *string    `json:"company,omitempty"`
+	Blog                        *string    `json:"blog,omitempty"`
+	Location                    *string    `json:"location,omitempty"`
+	Email                       *string    `json:"email,omitempty"`
+	Description                 *string    `json:"description,omitempty"`
+	PublicRepos                 *int       `json:"public_repos,omitempty"`
+	PublicGists                 *int       `json:"public_gists,omitempty"`
+	Followers                   *int       `json:"followers,omitempty"`
+	Following                   *int       `json:"following,omitempty"`
+	CreatedAt                   *time.Time `json:"created_at,omitempty"`
+	UpdatedAt                   *time.Time `json:"updated_at,omitempty"`
+	TotalPrivateRepos           *int       `json:"total_private_repos,omitempty"`
+	OwnedPrivateRepos           *int       `json:"owned_private_repos,omitempty"`
+	PrivateGists                *int       `json:"private_gists,omitempty"`
+	DiskUsage                   *int       `json:"disk_usage,omitempty"`
+	Collaborators               *int       `json:"collaborators,omitempty"`
+	BillingEmail                *string    `json:"billing_email,omitempty"`
+	Type                        *string    `json:"type,omitempty"`
+	Plan                        *Plan      `json:"plan,omitempty"`
+	TwoFactorRequirementEnabled *bool      `json:"two_factor_requirement_enabled,omitempty"`
+
+	// DefaultRepoPermission can be one of: "read", "write", "admin", or "none". (Default: "read").
+	// It is only used in OrganizationsService.Edit.
+	DefaultRepoPermission *string `json:"default_repository_permission,omitempty"`
+	// DefaultRepoSettings can be one of: "read", "write", "admin", or "none". (Default: "read").
+	// It is only used in OrganizationsService.Get.
+	DefaultRepoSettings *string `json:"default_repository_settings,omitempty"`
+
+	// MembersCanCreateRepos default value is true and is only used in Organizations.Edit.
+	MembersCanCreateRepos *bool `json:"members_can_create_repositories,omitempty"`
+
+	// API URLs
+	URL              *string `json:"url,omitempty"`
+	EventsURL        *string `json:"events_url,omitempty"`
+	HooksURL         *string `json:"hooks_url,omitempty"`
+	IssuesURL        *string `json:"issues_url,omitempty"`
+	MembersURL       *string `json:"members_url,omitempty"`
+	PublicMembersURL *string `json:"public_members_url,omitempty"`
+	ReposURL         *string `json:"repos_url,omitempty"`
+}
+
+func (o Organization) String() string {
+	return Stringify(o)
+}
+
+// Plan represents the payment plan for an account. See plans at https://github.com/plans.
+type Plan struct {
+	Name          *string `json:"name,omitempty"`
+	Space         *int    `json:"space,omitempty"`
+	Collaborators *int    `json:"collaborators,omitempty"`
+	PrivateRepos  *int    `json:"private_repos,omitempty"`
+}
+
+func (p Plan) String() string {
+	return Stringify(p)
+}
+
+// OrganizationsListOptions specifies the optional parameters to the
+// OrganizationsService.ListAll method.
+type OrganizationsListOptions struct {
+	// Since filters Organizations by ID.
+	Since int64 `url:"since,omitempty"`
+
+	// Note: Pagination is powered exclusively by the Since parameter,
+	// ListOptions.Page has no effect.
+	// ListOptions.PerPage controls an undocumented GitHub API parameter.
+	ListOptions
+}
+
+// ListAll lists all organizations, in the order that they were created on GitHub.
+//
+// Note: Pagination is powered exclusively by the since parameter. To continue
+// listing the next set of organizations, use the ID of the last-returned organization
+// as the opts.Since parameter for the next call.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/#list-all-organizations
+func (s *OrganizationsService) ListAll(ctx context.Context, opt *OrganizationsListOptions) ([]*Organization, *Response, error) {
+	u, err := addOptions("organizations", opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	orgs := []*Organization{}
+	resp, err := s.client.Do(ctx, req, &orgs)
+	if err != nil {
+		return nil, resp, err
+	}
+	return orgs, resp, nil
+}
+
+// List the organizations for a user. Passing the empty string will list
+// organizations for the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/#list-user-organizations
+func (s *OrganizationsService) List(ctx context.Context, user string, opt *ListOptions) ([]*Organization, *Response, error) {
+	var u string
+	if user != "" {
+		u = fmt.Sprintf("users/%v/orgs", user)
+	} else {
+		u = "user/orgs"
+	}
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var orgs []*Organization
+	resp, err := s.client.Do(ctx, req, &orgs)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return orgs, resp, nil
+}
+
+// Get fetches an organization by name.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/#get-an-organization
+func (s *OrganizationsService) Get(ctx context.Context, org string) (*Organization, *Response, error) {
+	u := fmt.Sprintf("orgs/%v", org)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	organization := new(Organization)
+	resp, err := s.client.Do(ctx, req, organization)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return organization, resp, nil
+}
+
+// GetByID fetches an organization.
+//
+// Note: GetByID uses the undocumented GitHub API endpoint /organizations/:id.
+func (s *OrganizationsService) GetByID(ctx context.Context, id int64) (*Organization, *Response, error) {
+	u := fmt.Sprintf("organizations/%d", id)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	organization := new(Organization)
+	resp, err := s.client.Do(ctx, req, organization)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return organization, resp, nil
+}
+
+// Edit an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/#edit-an-organization
+func (s *OrganizationsService) Edit(ctx context.Context, name string, org *Organization) (*Organization, *Response, error) {
+	u := fmt.Sprintf("orgs/%v", name)
+	req, err := s.client.NewRequest("PATCH", u, org)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	o := new(Organization)
+	resp, err := s.client.Do(ctx, req, o)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return o, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/orgs_hooks.go b/vendor/github.com/google/go-github/v24/github/orgs_hooks.go
new file mode 100644
index 000000000..b710ea402
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/orgs_hooks.go
@@ -0,0 +1,117 @@
+// Copyright 2015 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// ListHooks lists all Hooks for the specified organization.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#list-hooks
+func (s *OrganizationsService) ListHooks(ctx context.Context, org string, opt *ListOptions) ([]*Hook, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/hooks", org)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var hooks []*Hook
+	resp, err := s.client.Do(ctx, req, &hooks)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return hooks, resp, nil
+}
+
+// GetHook returns a single specified Hook.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#get-single-hook
+func (s *OrganizationsService) GetHook(ctx context.Context, org string, id int64) (*Hook, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/hooks/%d", org, id)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+	hook := new(Hook)
+	resp, err := s.client.Do(ctx, req, hook)
+	return hook, resp, err
+}
+
+// CreateHook creates a Hook for the specified org.
+// Config is a required field.
+//
+// Note that only a subset of the hook fields are used and hook must
+// not be nil.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#create-a-hook
+func (s *OrganizationsService) CreateHook(ctx context.Context, org string, hook *Hook) (*Hook, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/hooks", org)
+
+	hookReq := &createHookRequest{
+		Events: hook.Events,
+		Active: hook.Active,
+		Config: hook.Config,
+	}
+
+	req, err := s.client.NewRequest("POST", u, hookReq)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	h := new(Hook)
+	resp, err := s.client.Do(ctx, req, h)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return h, resp, nil
+}
+
+// EditHook updates a specified Hook.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#edit-a-hook
+func (s *OrganizationsService) EditHook(ctx context.Context, org string, id int64, hook *Hook) (*Hook, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/hooks/%d", org, id)
+	req, err := s.client.NewRequest("PATCH", u, hook)
+	if err != nil {
+		return nil, nil, err
+	}
+	h := new(Hook)
+	resp, err := s.client.Do(ctx, req, h)
+	return h, resp, err
+}
+
+// PingHook triggers a 'ping' event to be sent to the Hook.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#ping-a-hook
+func (s *OrganizationsService) PingHook(ctx context.Context, org string, id int64) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/hooks/%d/pings", org, id)
+	req, err := s.client.NewRequest("POST", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
+
+// DeleteHook deletes a specified Hook.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#delete-a-hook
+func (s *OrganizationsService) DeleteHook(ctx context.Context, org string, id int64) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/hooks/%d", org, id)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/orgs_members.go b/vendor/github.com/google/go-github/v24/github/orgs_members.go
new file mode 100644
index 000000000..d18435999
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/orgs_members.go
@@ -0,0 +1,370 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// Membership represents the status of a user's membership in an organization or team.
+type Membership struct {
+	URL *string `json:"url,omitempty"`
+
+	// State is the user's status within the organization or team.
+	// Possible values are: "active", "pending"
+	State *string `json:"state,omitempty"`
+
+	// Role identifies the user's role within the organization or team.
+	// Possible values for organization membership:
+	//     member - non-owner organization member
+	//     admin - organization owner
+	//
+	// Possible values for team membership are:
+	//     member - a normal member of the team
+	//     maintainer - a team maintainer. Able to add/remove other team
+	//                  members, promote other team members to team
+	//                  maintainer, and edit the team’s name and description
+	Role *string `json:"role,omitempty"`
+
+	// For organization membership, the API URL of the organization.
+	OrganizationURL *string `json:"organization_url,omitempty"`
+
+	// For organization membership, the organization the membership is for.
+	Organization *Organization `json:"organization,omitempty"`
+
+	// For organization membership, the user the membership is for.
+	User *User `json:"user,omitempty"`
+}
+
+func (m Membership) String() string {
+	return Stringify(m)
+}
+
+// ListMembersOptions specifies optional parameters to the
+// OrganizationsService.ListMembers method.
+type ListMembersOptions struct {
+	// If true (or if the authenticated user is not an owner of the
+	// organization), list only publicly visible members.
+	PublicOnly bool `url:"-"`
+
+	// Filter members returned in the list. Possible values are:
+	// 2fa_disabled, all. Default is "all".
+	Filter string `url:"filter,omitempty"`
+
+	// Role filters members returned by their role in the organization.
+	// Possible values are:
+	//     all - all members of the organization, regardless of role
+	//     admin - organization owners
+	//     member - non-owner organization members
+	//
+	// Default is "all".
+	Role string `url:"role,omitempty"`
+
+	ListOptions
+}
+
+// ListMembers lists the members for an organization. If the authenticated
+// user is an owner of the organization, this will return both concealed and
+// public members, otherwise it will only return public members.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/members/#members-list
+func (s *OrganizationsService) ListMembers(ctx context.Context, org string, opt *ListMembersOptions) ([]*User, *Response, error) {
+	var u string
+	if opt != nil && opt.PublicOnly {
+		u = fmt.Sprintf("orgs/%v/public_members", org)
+	} else {
+		u = fmt.Sprintf("orgs/%v/members", org)
+	}
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var members []*User
+	resp, err := s.client.Do(ctx, req, &members)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return members, resp, nil
+}
+
+// IsMember checks if a user is a member of an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/members/#check-membership
+func (s *OrganizationsService) IsMember(ctx context.Context, org, user string) (bool, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/members/%v", org, user)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return false, nil, err
+	}
+
+	resp, err := s.client.Do(ctx, req, nil)
+	member, err := parseBoolResponse(err)
+	return member, resp, err
+}
+
+// IsPublicMember checks if a user is a public member of an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/members/#check-public-membership
+func (s *OrganizationsService) IsPublicMember(ctx context.Context, org, user string) (bool, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/public_members/%v", org, user)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return false, nil, err
+	}
+
+	resp, err := s.client.Do(ctx, req, nil)
+	member, err := parseBoolResponse(err)
+	return member, resp, err
+}
+
+// RemoveMember removes a user from all teams of an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/members/#remove-a-member
+func (s *OrganizationsService) RemoveMember(ctx context.Context, org, user string) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/members/%v", org, user)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// PublicizeMembership publicizes a user's membership in an organization. (A
+// user cannot publicize the membership for another user.)
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/members/#publicize-a-users-membership
+func (s *OrganizationsService) PublicizeMembership(ctx context.Context, org, user string) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/public_members/%v", org, user)
+	req, err := s.client.NewRequest("PUT", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// ConcealMembership conceals a user's membership in an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/members/#conceal-a-users-membership
+func (s *OrganizationsService) ConcealMembership(ctx context.Context, org, user string) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/public_members/%v", org, user)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// ListOrgMembershipsOptions specifies optional parameters to the
+// OrganizationsService.ListOrgMemberships method.
+type ListOrgMembershipsOptions struct {
+	// Filter memberships to include only those with the specified state.
+	// Possible values are: "active", "pending".
+	State string `url:"state,omitempty"`
+
+	ListOptions
+}
+
+// ListOrgMemberships lists the organization memberships for the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/members/#list-your-organization-memberships
+func (s *OrganizationsService) ListOrgMemberships(ctx context.Context, opt *ListOrgMembershipsOptions) ([]*Membership, *Response, error) {
+	u := "user/memberships/orgs"
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var memberships []*Membership
+	resp, err := s.client.Do(ctx, req, &memberships)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return memberships, resp, nil
+}
+
+// GetOrgMembership gets the membership for a user in a specified organization.
+// Passing an empty string for user will get the membership for the
+// authenticated user.
+//
+// GitHub API docs:
+// https://developer.github.com/v3/orgs/members/#get-organization-membership
+// https://developer.github.com/v3/orgs/members/#get-your-organization-membership
+func (s *OrganizationsService) GetOrgMembership(ctx context.Context, user, org string) (*Membership, *Response, error) {
+	var u string
+	if user != "" {
+		u = fmt.Sprintf("orgs/%v/memberships/%v", org, user)
+	} else {
+		u = fmt.Sprintf("user/memberships/orgs/%v", org)
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	membership := new(Membership)
+	resp, err := s.client.Do(ctx, req, membership)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return membership, resp, nil
+}
+
+// EditOrgMembership edits the membership for user in specified organization.
+// Passing an empty string for user will edit the membership for the
+// authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/members/#add-or-update-organization-membership
+// GitHub API docs: https://developer.github.com/v3/orgs/members/#edit-your-organization-membership
+func (s *OrganizationsService) EditOrgMembership(ctx context.Context, user, org string, membership *Membership) (*Membership, *Response, error) {
+	var u, method string
+	if user != "" {
+		u = fmt.Sprintf("orgs/%v/memberships/%v", org, user)
+		method = "PUT"
+	} else {
+		u = fmt.Sprintf("user/memberships/orgs/%v", org)
+		method = "PATCH"
+	}
+
+	req, err := s.client.NewRequest(method, u, membership)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	m := new(Membership)
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// RemoveOrgMembership removes user from the specified organization. If the
+// user has been invited to the organization, this will cancel their invitation.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/members/#remove-organization-membership
+func (s *OrganizationsService) RemoveOrgMembership(ctx context.Context, user, org string) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/memberships/%v", org, user)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// ListPendingOrgInvitations returns a list of pending invitations.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/members/#list-pending-organization-invitations
+func (s *OrganizationsService) ListPendingOrgInvitations(ctx context.Context, org string, opt *ListOptions) ([]*Invitation, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/invitations", org)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var pendingInvitations []*Invitation
+	resp, err := s.client.Do(ctx, req, &pendingInvitations)
+	if err != nil {
+		return nil, resp, err
+	}
+	return pendingInvitations, resp, nil
+}
+
+// CreateOrgInvitationOptions specifies the parameters to the OrganizationService.Invite
+// method.
+type CreateOrgInvitationOptions struct {
+	// GitHub user ID for the person you are inviting. Not required if you provide Email.
+	InviteeID *int64 `json:"invitee_id,omitempty"`
+	// Email address of the person you are inviting, which can be an existing GitHub user.
+	// Not required if you provide InviteeID
+	Email *string `json:"email,omitempty"`
+	// Specify role for new member. Can be one of:
+	// * admin - Organization owners with full administrative rights to the
+	// 	 organization and complete access to all repositories and teams.
+	// * direct_member - Non-owner organization members with ability to see
+	//   other members and join teams by invitation.
+	// * billing_manager - Non-owner organization members with ability to
+	//   manage the billing settings of your organization.
+	// Default is "direct_member".
+	Role   *string `json:"role"`
+	TeamID []int64 `json:"team_ids"`
+}
+
+// CreateOrgInvitation invites people to an organization by using their GitHub user ID or their email address.
+// In order to create invitations in an organization,
+// the authenticated user must be an organization owner.
+//
+// https://developer.github.com/v3/orgs/members/#create-organization-invitation
+func (s *OrganizationsService) CreateOrgInvitation(ctx context.Context, org string, opt *CreateOrgInvitationOptions) (*Invitation, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/invitations", org)
+
+	req, err := s.client.NewRequest("POST", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeOrganizationInvitationPreview)
+
+	var invitation *Invitation
+	resp, err := s.client.Do(ctx, req, &invitation)
+	if err != nil {
+		return nil, resp, err
+	}
+	return invitation, resp, nil
+}
+
+// ListOrgInvitationTeams lists all teams associated with an invitation. In order to see invitations in an organization,
+// the authenticated user must be an organization owner.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/members/#list-organization-invitation-teams
+func (s *OrganizationsService) ListOrgInvitationTeams(ctx context.Context, org, invitationID string, opt *ListOptions) ([]*Team, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/invitations/%v/teams", org, invitationID)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeOrganizationInvitationPreview)
+
+	var orgInvitationTeams []*Team
+	resp, err := s.client.Do(ctx, req, &orgInvitationTeams)
+	if err != nil {
+		return nil, resp, err
+	}
+	return orgInvitationTeams, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/orgs_outside_collaborators.go b/vendor/github.com/google/go-github/v24/github/orgs_outside_collaborators.go
new file mode 100644
index 000000000..85ffd05f6
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/orgs_outside_collaborators.go
@@ -0,0 +1,81 @@
+// Copyright 2017 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// ListOutsideCollaboratorsOptions specifies optional parameters to the
+// OrganizationsService.ListOutsideCollaborators method.
+type ListOutsideCollaboratorsOptions struct {
+	// Filter outside collaborators returned in the list. Possible values are:
+	// 2fa_disabled, all.  Default is "all".
+	Filter string `url:"filter,omitempty"`
+
+	ListOptions
+}
+
+// ListOutsideCollaborators lists outside collaborators of organization's repositories.
+// This will only work if the authenticated
+// user is an owner of the organization.
+//
+// Warning: The API may change without advance notice during the preview period.
+// Preview features are not supported for production use.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/outside_collaborators/#list-outside-collaborators
+func (s *OrganizationsService) ListOutsideCollaborators(ctx context.Context, org string, opt *ListOutsideCollaboratorsOptions) ([]*User, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/outside_collaborators", org)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var members []*User
+	resp, err := s.client.Do(ctx, req, &members)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return members, resp, nil
+}
+
+// RemoveOutsideCollaborator removes a user from the list of outside collaborators;
+// consequently, removing them from all the organization's repositories.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/outside_collaborators/#remove-outside-collaborator
+func (s *OrganizationsService) RemoveOutsideCollaborator(ctx context.Context, org string, user string) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/outside_collaborators/%v", org, user)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// ConvertMemberToOutsideCollaborator reduces the permission level of a member of the
+// organization to that of an outside collaborator. Therefore, they will only
+// have access to the repositories that their current team membership allows.
+// Responses for converting a non-member or the last owner to an outside collaborator
+// are listed in GitHub API docs.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/outside_collaborators/#convert-member-to-outside-collaborator
+func (s *OrganizationsService) ConvertMemberToOutsideCollaborator(ctx context.Context, org string, user string) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/outside_collaborators/%v", org, user)
+	req, err := s.client.NewRequest("PUT", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/orgs_projects.go b/vendor/github.com/google/go-github/v24/github/orgs_projects.go
new file mode 100644
index 000000000..e57cba978
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/orgs_projects.go
@@ -0,0 +1,60 @@
+// Copyright 2017 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// ListProjects lists the projects for an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/#list-organization-projects
+func (s *OrganizationsService) ListProjects(ctx context.Context, org string, opt *ProjectListOptions) ([]*Project, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/projects", org)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	var projects []*Project
+	resp, err := s.client.Do(ctx, req, &projects)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return projects, resp, nil
+}
+
+// CreateProject creates a GitHub Project for the specified organization.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/#create-an-organization-project
+func (s *OrganizationsService) CreateProject(ctx context.Context, org string, opt *ProjectOptions) (*Project, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/projects", org)
+	req, err := s.client.NewRequest("POST", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	project := &Project{}
+	resp, err := s.client.Do(ctx, req, project)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return project, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/orgs_users_blocking.go b/vendor/github.com/google/go-github/v24/github/orgs_users_blocking.go
new file mode 100644
index 000000000..b1aecf445
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/orgs_users_blocking.go
@@ -0,0 +1,91 @@
+// Copyright 2017 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// ListBlockedUsers lists all the users blocked by an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/blocking/#list-blocked-users
+func (s *OrganizationsService) ListBlockedUsers(ctx context.Context, org string, opt *ListOptions) ([]*User, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/blocks", org)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeBlockUsersPreview)
+
+	var blockedUsers []*User
+	resp, err := s.client.Do(ctx, req, &blockedUsers)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return blockedUsers, resp, nil
+}
+
+// IsBlocked reports whether specified user is blocked from an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/blocking/#check-whether-a-user-is-blocked-from-an-organization
+func (s *OrganizationsService) IsBlocked(ctx context.Context, org string, user string) (bool, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/blocks/%v", org, user)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return false, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeBlockUsersPreview)
+
+	resp, err := s.client.Do(ctx, req, nil)
+	isBlocked, err := parseBoolResponse(err)
+	return isBlocked, resp, err
+}
+
+// BlockUser blocks specified user from an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/blocking/#block-a-user
+func (s *OrganizationsService) BlockUser(ctx context.Context, org string, user string) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/blocks/%v", org, user)
+
+	req, err := s.client.NewRequest("PUT", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeBlockUsersPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// UnblockUser unblocks specified user from an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/blocking/#unblock-a-user
+func (s *OrganizationsService) UnblockUser(ctx context.Context, org string, user string) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/blocks/%v", org, user)
+
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeBlockUsersPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/projects.go b/vendor/github.com/google/go-github/v24/github/projects.go
new file mode 100644
index 000000000..c7a68f53d
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/projects.go
@@ -0,0 +1,594 @@
+// Copyright 2016 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// ProjectsService provides access to the projects functions in the
+// GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/
+type ProjectsService service
+
+// Project represents a GitHub Project.
+type Project struct {
+	ID         *int64     `json:"id,omitempty"`
+	URL        *string    `json:"url,omitempty"`
+	HTMLURL    *string    `json:"html_url,omitempty"`
+	ColumnsURL *string    `json:"columns_url,omitempty"`
+	OwnerURL   *string    `json:"owner_url,omitempty"`
+	Name       *string    `json:"name,omitempty"`
+	Body       *string    `json:"body,omitempty"`
+	Number     *int       `json:"number,omitempty"`
+	State      *string    `json:"state,omitempty"`
+	CreatedAt  *Timestamp `json:"created_at,omitempty"`
+	UpdatedAt  *Timestamp `json:"updated_at,omitempty"`
+	NodeID     *string    `json:"node_id,omitempty"`
+
+	// The User object that generated the project.
+	Creator *User `json:"creator,omitempty"`
+}
+
+func (p Project) String() string {
+	return Stringify(p)
+}
+
+// GetProject gets a GitHub Project for a repo.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/#get-a-project
+func (s *ProjectsService) GetProject(ctx context.Context, id int64) (*Project, *Response, error) {
+	u := fmt.Sprintf("projects/%v", id)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	project := &Project{}
+	resp, err := s.client.Do(ctx, req, project)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return project, resp, nil
+}
+
+// ProjectOptions specifies the parameters to the
+// RepositoriesService.CreateProject and
+// ProjectsService.UpdateProject methods.
+type ProjectOptions struct {
+	// The name of the project. (Required for creation; optional for update.)
+	Name *string `json:"name,omitempty"`
+	// The body of the project. (Optional.)
+	Body *string `json:"body,omitempty"`
+
+	// The following field(s) are only applicable for update.
+	// They should be left with zero values for creation.
+
+	// State of the project. Either "open" or "closed". (Optional.)
+	State *string `json:"state,omitempty"`
+	// The permission level that all members of the project's organization
+	// will have on this project.
+	// Setting the organization permission is only available
+	// for organization projects. (Optional.)
+	OrganizationPermission *string `json:"organization_permission,omitempty"`
+	// Sets visibility of the project within the organization.
+	// Setting visibility is only available
+	// for organization projects.(Optional.)
+	Public *bool `json:"public,omitempty"`
+}
+
+// UpdateProject updates a repository project.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/#update-a-project
+func (s *ProjectsService) UpdateProject(ctx context.Context, id int64, opt *ProjectOptions) (*Project, *Response, error) {
+	u := fmt.Sprintf("projects/%v", id)
+	req, err := s.client.NewRequest("PATCH", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	project := &Project{}
+	resp, err := s.client.Do(ctx, req, project)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return project, resp, nil
+}
+
+// DeleteProject deletes a GitHub Project from a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/#delete-a-project
+func (s *ProjectsService) DeleteProject(ctx context.Context, id int64) (*Response, error) {
+	u := fmt.Sprintf("projects/%v", id)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// ProjectColumn represents a column of a GitHub Project.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/projects/
+type ProjectColumn struct {
+	ID         *int64     `json:"id,omitempty"`
+	Name       *string    `json:"name,omitempty"`
+	URL        *string    `json:"url,omitempty"`
+	ProjectURL *string    `json:"project_url,omitempty"`
+	CardsURL   *string    `json:"cards_url,omitempty"`
+	CreatedAt  *Timestamp `json:"created_at,omitempty"`
+	UpdatedAt  *Timestamp `json:"updated_at,omitempty"`
+	NodeID     *string    `json:"node_id,omitempty"`
+}
+
+// ListProjectColumns lists the columns of a GitHub Project for a repo.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/columns/#list-project-columns
+func (s *ProjectsService) ListProjectColumns(ctx context.Context, projectID int64, opt *ListOptions) ([]*ProjectColumn, *Response, error) {
+	u := fmt.Sprintf("projects/%v/columns", projectID)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	columns := []*ProjectColumn{}
+	resp, err := s.client.Do(ctx, req, &columns)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return columns, resp, nil
+}
+
+// GetProjectColumn gets a column of a GitHub Project for a repo.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/columns/#get-a-project-column
+func (s *ProjectsService) GetProjectColumn(ctx context.Context, id int64) (*ProjectColumn, *Response, error) {
+	u := fmt.Sprintf("projects/columns/%v", id)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	column := &ProjectColumn{}
+	resp, err := s.client.Do(ctx, req, column)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return column, resp, nil
+}
+
+// ProjectColumnOptions specifies the parameters to the
+// ProjectsService.CreateProjectColumn and
+// ProjectsService.UpdateProjectColumn methods.
+type ProjectColumnOptions struct {
+	// The name of the project column. (Required for creation and update.)
+	Name string `json:"name"`
+}
+
+// CreateProjectColumn creates a column for the specified (by number) project.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/columns/#create-a-project-column
+func (s *ProjectsService) CreateProjectColumn(ctx context.Context, projectID int64, opt *ProjectColumnOptions) (*ProjectColumn, *Response, error) {
+	u := fmt.Sprintf("projects/%v/columns", projectID)
+	req, err := s.client.NewRequest("POST", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	column := &ProjectColumn{}
+	resp, err := s.client.Do(ctx, req, column)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return column, resp, nil
+}
+
+// UpdateProjectColumn updates a column of a GitHub Project.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/columns/#update-a-project-column
+func (s *ProjectsService) UpdateProjectColumn(ctx context.Context, columnID int64, opt *ProjectColumnOptions) (*ProjectColumn, *Response, error) {
+	u := fmt.Sprintf("projects/columns/%v", columnID)
+	req, err := s.client.NewRequest("PATCH", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	column := &ProjectColumn{}
+	resp, err := s.client.Do(ctx, req, column)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return column, resp, nil
+}
+
+// DeleteProjectColumn deletes a column from a GitHub Project.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/columns/#delete-a-project-column
+func (s *ProjectsService) DeleteProjectColumn(ctx context.Context, columnID int64) (*Response, error) {
+	u := fmt.Sprintf("projects/columns/%v", columnID)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// ProjectColumnMoveOptions specifies the parameters to the
+// ProjectsService.MoveProjectColumn method.
+type ProjectColumnMoveOptions struct {
+	// Position can be one of "first", "last", or "after:<column-id>", where
+	// <column-id> is the ID of a column in the same project. (Required.)
+	Position string `json:"position"`
+}
+
+// MoveProjectColumn moves a column within a GitHub Project.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/columns/#move-a-project-column
+func (s *ProjectsService) MoveProjectColumn(ctx context.Context, columnID int64, opt *ProjectColumnMoveOptions) (*Response, error) {
+	u := fmt.Sprintf("projects/columns/%v/moves", columnID)
+	req, err := s.client.NewRequest("POST", u, opt)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// ProjectCard represents a card in a column of a GitHub Project.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/cards/#get-a-project-card
+type ProjectCard struct {
+	URL        *string    `json:"url,omitempty"`
+	ColumnURL  *string    `json:"column_url,omitempty"`
+	ContentURL *string    `json:"content_url,omitempty"`
+	ID         *int64     `json:"id,omitempty"`
+	Note       *string    `json:"note,omitempty"`
+	Creator    *User      `json:"creator,omitempty"`
+	CreatedAt  *Timestamp `json:"created_at,omitempty"`
+	UpdatedAt  *Timestamp `json:"updated_at,omitempty"`
+	NodeID     *string    `json:"node_id,omitempty"`
+	Archived   *bool      `json:"archived,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	ColumnID *int64 `json:"column_id,omitempty"`
+
+	// The following fields are only populated by Events API.
+	ProjectID          *int64  `json:"project_id,omitempty"`
+	ProjectURL         *string `json:"project_url,omitempty"`
+	ColumnName         *string `json:"column_name,omitempty"`
+	PreviousColumnName *string `json:"previous_column_name,omitempty"` // Populated in "moved_columns_in_project" event deliveries.
+}
+
+// ProjectCardListOptions specifies the optional parameters to the
+// ProjectsService.ListProjectCards method.
+type ProjectCardListOptions struct {
+	// ArchivedState is used to list all, archived, or not_archived project cards.
+	// Defaults to not_archived when you omit this parameter.
+	ArchivedState *string `url:"archived_state,omitempty"`
+
+	ListOptions
+}
+
+// ListProjectCards lists the cards in a column of a GitHub Project.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/cards/#list-project-cards
+func (s *ProjectsService) ListProjectCards(ctx context.Context, columnID int64, opt *ProjectCardListOptions) ([]*ProjectCard, *Response, error) {
+	u := fmt.Sprintf("projects/columns/%v/cards", columnID)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	cards := []*ProjectCard{}
+	resp, err := s.client.Do(ctx, req, &cards)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return cards, resp, nil
+}
+
+// GetProjectCard gets a card in a column of a GitHub Project.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/cards/#get-a-project-card
+func (s *ProjectsService) GetProjectCard(ctx context.Context, columnID int64) (*ProjectCard, *Response, error) {
+	u := fmt.Sprintf("projects/columns/cards/%v", columnID)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	card := &ProjectCard{}
+	resp, err := s.client.Do(ctx, req, card)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return card, resp, nil
+}
+
+// ProjectCardOptions specifies the parameters to the
+// ProjectsService.CreateProjectCard and
+// ProjectsService.UpdateProjectCard methods.
+type ProjectCardOptions struct {
+	// The note of the card. Note and ContentID are mutually exclusive.
+	Note string `json:"note,omitempty"`
+	// The ID (not Number) of the Issue to associate with this card.
+	// Note and ContentID are mutually exclusive.
+	ContentID int64 `json:"content_id,omitempty"`
+	// The type of content to associate with this card. Possible values are: "Issue" and "PullRequest".
+	ContentType string `json:"content_type,omitempty"`
+	// Use true to archive a project card.
+	// Specify false if you need to restore a previously archived project card.
+	Archived *bool `json:"archived,omitempty"`
+}
+
+// CreateProjectCard creates a card in the specified column of a GitHub Project.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/cards/#create-a-project-card
+func (s *ProjectsService) CreateProjectCard(ctx context.Context, columnID int64, opt *ProjectCardOptions) (*ProjectCard, *Response, error) {
+	u := fmt.Sprintf("projects/columns/%v/cards", columnID)
+	req, err := s.client.NewRequest("POST", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	card := &ProjectCard{}
+	resp, err := s.client.Do(ctx, req, card)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return card, resp, nil
+}
+
+// UpdateProjectCard updates a card of a GitHub Project.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/cards/#update-a-project-card
+func (s *ProjectsService) UpdateProjectCard(ctx context.Context, cardID int64, opt *ProjectCardOptions) (*ProjectCard, *Response, error) {
+	u := fmt.Sprintf("projects/columns/cards/%v", cardID)
+	req, err := s.client.NewRequest("PATCH", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	card := &ProjectCard{}
+	resp, err := s.client.Do(ctx, req, card)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return card, resp, nil
+}
+
+// DeleteProjectCard deletes a card from a GitHub Project.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/cards/#delete-a-project-card
+func (s *ProjectsService) DeleteProjectCard(ctx context.Context, cardID int64) (*Response, error) {
+	u := fmt.Sprintf("projects/columns/cards/%v", cardID)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// ProjectCardMoveOptions specifies the parameters to the
+// ProjectsService.MoveProjectCard method.
+type ProjectCardMoveOptions struct {
+	// Position can be one of "top", "bottom", or "after:<card-id>", where
+	// <card-id> is the ID of a card in the same project.
+	Position string `json:"position"`
+	// ColumnID is the ID of a column in the same project. Note that ColumnID
+	// is required when using Position "after:<card-id>" when that card is in
+	// another column; otherwise it is optional.
+	ColumnID int64 `json:"column_id,omitempty"`
+}
+
+// MoveProjectCard moves a card within a GitHub Project.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/cards/#move-a-project-card
+func (s *ProjectsService) MoveProjectCard(ctx context.Context, cardID int64, opt *ProjectCardMoveOptions) (*Response, error) {
+	u := fmt.Sprintf("projects/columns/cards/%v/moves", cardID)
+	req, err := s.client.NewRequest("POST", u, opt)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// ProjectCollaboratorOptions specifies the optional parameters to the
+// ProjectsService.AddProjectCollaborator method.
+type ProjectCollaboratorOptions struct {
+	// Permission specifies the permission to grant to the collaborator.
+	// Possible values are:
+	//     "read" - can read, but not write to or administer this project.
+	//     "write" - can read and write, but not administer this project.
+	//     "admin" - can read, write and administer this project.
+	//
+	// Default value is "write"
+	Permission *string `json:"permission,omitempty"`
+}
+
+// AddProjectCollaborator adds a collaborator to an organization project and sets
+// their permission level. You must be an organization owner or a project admin to add a collaborator.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/collaborators/#add-user-as-a-collaborator
+func (s *ProjectsService) AddProjectCollaborator(ctx context.Context, id int64, username string, opt *ProjectCollaboratorOptions) (*Response, error) {
+	u := fmt.Sprintf("projects/%v/collaborators/%v", id, username)
+	req, err := s.client.NewRequest("PUT", u, opt)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// RemoveProjectCollaborator removes a collaborator from an organization project.
+// You must be an organization owner or a project admin to remove a collaborator.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/collaborators/#remove-user-as-a-collaborator
+func (s *ProjectsService) RemoveProjectCollaborator(ctx context.Context, id int64, username string) (*Response, error) {
+	u := fmt.Sprintf("projects/%v/collaborators/%v", id, username)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// ListCollaboratorOptions specifies the optional parameters to the
+// ProjectsService.ListProjectCollaborators method.
+type ListCollaboratorOptions struct {
+	// Affiliation specifies how collaborators should be filtered by their affiliation.
+	// Possible values are:
+	//     "outside" - All outside collaborators of an organization-owned repository
+	//     "direct" - All collaborators with permissions to an organization-owned repository,
+	//              regardless of organization membership status
+	//     "all" - All collaborators the authenticated user can see
+	//
+	// Default value is "all".
+	Affiliation *string `url:"affiliation,omitempty"`
+
+	ListOptions
+}
+
+// ListProjectCollaborators lists the collaborators for an organization project. For a project,
+// the list of collaborators includes outside collaborators, organization members that are direct
+// collaborators, organization members with access through team memberships, organization members
+// with access through default organization permissions, and organization owners. You must be an
+// organization owner or a project admin to list collaborators.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/collaborators/#list-collaborators
+func (s *ProjectsService) ListProjectCollaborators(ctx context.Context, id int64, opt *ListCollaboratorOptions) ([]*User, *Response, error) {
+	u := fmt.Sprintf("projects/%v/collaborators", id)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	var users []*User
+	resp, err := s.client.Do(ctx, req, &users)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return users, resp, nil
+}
+
+// ProjectPermissionLevel represents the permission level an organization
+// member has for a given project.
+type ProjectPermissionLevel struct {
+	// Possible values: "admin", "write", "read", "none"
+	Permission *string `json:"permission,omitempty"`
+
+	User *User `json:"user,omitempty"`
+}
+
+// ReviewProjectCollaboratorPermission returns the collaborator's permission level for an organization
+// project. Possible values for the permission key: "admin", "write", "read", "none".
+// You must be an organization owner or a project admin to review a user's permission level.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/collaborators/#review-a-users-permission-level
+func (s *ProjectsService) ReviewProjectCollaboratorPermission(ctx context.Context, id int64, username string) (*ProjectPermissionLevel, *Response, error) {
+	u := fmt.Sprintf("projects/%v/collaborators/%v/permission", id, username)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	ppl := new(ProjectPermissionLevel)
+	resp, err := s.client.Do(ctx, req, ppl)
+	if err != nil {
+		return nil, resp, err
+	}
+	return ppl, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/pulls.go b/vendor/github.com/google/go-github/v24/github/pulls.go
new file mode 100644
index 000000000..067e362be
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/pulls.go
@@ -0,0 +1,404 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"strings"
+	"time"
+)
+
+// PullRequestsService handles communication with the pull request related
+// methods of the GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/
+type PullRequestsService service
+
+// PullRequest represents a GitHub pull request on a repository.
+type PullRequest struct {
+	ID                  *int64     `json:"id,omitempty"`
+	Number              *int       `json:"number,omitempty"`
+	State               *string    `json:"state,omitempty"`
+	Title               *string    `json:"title,omitempty"`
+	Body                *string    `json:"body,omitempty"`
+	CreatedAt           *time.Time `json:"created_at,omitempty"`
+	UpdatedAt           *time.Time `json:"updated_at,omitempty"`
+	ClosedAt            *time.Time `json:"closed_at,omitempty"`
+	MergedAt            *time.Time `json:"merged_at,omitempty"`
+	Labels              []*Label   `json:"labels,omitempty"`
+	User                *User      `json:"user,omitempty"`
+	Draft               *bool      `json:"draft,omitempty"`
+	Merged              *bool      `json:"merged,omitempty"`
+	Mergeable           *bool      `json:"mergeable,omitempty"`
+	MergeableState      *string    `json:"mergeable_state,omitempty"`
+	MergedBy            *User      `json:"merged_by,omitempty"`
+	MergeCommitSHA      *string    `json:"merge_commit_sha,omitempty"`
+	Comments            *int       `json:"comments,omitempty"`
+	Commits             *int       `json:"commits,omitempty"`
+	Additions           *int       `json:"additions,omitempty"`
+	Deletions           *int       `json:"deletions,omitempty"`
+	ChangedFiles        *int       `json:"changed_files,omitempty"`
+	URL                 *string    `json:"url,omitempty"`
+	HTMLURL             *string    `json:"html_url,omitempty"`
+	IssueURL            *string    `json:"issue_url,omitempty"`
+	StatusesURL         *string    `json:"statuses_url,omitempty"`
+	DiffURL             *string    `json:"diff_url,omitempty"`
+	PatchURL            *string    `json:"patch_url,omitempty"`
+	CommitsURL          *string    `json:"commits_url,omitempty"`
+	CommentsURL         *string    `json:"comments_url,omitempty"`
+	ReviewCommentsURL   *string    `json:"review_comments_url,omitempty"`
+	ReviewCommentURL    *string    `json:"review_comment_url,omitempty"`
+	ReviewComments      *int       `json:"review_comments,omitempty"`
+	Assignee            *User      `json:"assignee,omitempty"`
+	Assignees           []*User    `json:"assignees,omitempty"`
+	Milestone           *Milestone `json:"milestone,omitempty"`
+	MaintainerCanModify *bool      `json:"maintainer_can_modify,omitempty"`
+	AuthorAssociation   *string    `json:"author_association,omitempty"`
+	NodeID              *string    `json:"node_id,omitempty"`
+	RequestedReviewers  []*User    `json:"requested_reviewers,omitempty"`
+
+	// RequestedTeams is populated as part of the PullRequestEvent.
+	// See, https://developer.github.com/v3/activity/events/types/#pullrequestevent for an example.
+	RequestedTeams []*Team `json:"requested_teams,omitempty"`
+
+	Links *PRLinks           `json:"_links,omitempty"`
+	Head  *PullRequestBranch `json:"head,omitempty"`
+	Base  *PullRequestBranch `json:"base,omitempty"`
+
+	// ActiveLockReason is populated only when LockReason is provided while locking the pull request.
+	// Possible values are: "off-topic", "too heated", "resolved", and "spam".
+	ActiveLockReason *string `json:"active_lock_reason,omitempty"`
+}
+
+func (p PullRequest) String() string {
+	return Stringify(p)
+}
+
+// PRLink represents a single link object from Github pull request _links.
+type PRLink struct {
+	HRef *string `json:"href,omitempty"`
+}
+
+// PRLinks represents the "_links" object in a Github pull request.
+type PRLinks struct {
+	Self           *PRLink `json:"self,omitempty"`
+	HTML           *PRLink `json:"html,omitempty"`
+	Issue          *PRLink `json:"issue,omitempty"`
+	Comments       *PRLink `json:"comments,omitempty"`
+	ReviewComments *PRLink `json:"review_comments,omitempty"`
+	ReviewComment  *PRLink `json:"review_comment,omitempty"`
+	Commits        *PRLink `json:"commits,omitempty"`
+	Statuses       *PRLink `json:"statuses,omitempty"`
+}
+
+// PullRequestBranch represents a base or head branch in a GitHub pull request.
+type PullRequestBranch struct {
+	Label *string     `json:"label,omitempty"`
+	Ref   *string     `json:"ref,omitempty"`
+	SHA   *string     `json:"sha,omitempty"`
+	Repo  *Repository `json:"repo,omitempty"`
+	User  *User       `json:"user,omitempty"`
+}
+
+// PullRequestListOptions specifies the optional parameters to the
+// PullRequestsService.List method.
+type PullRequestListOptions struct {
+	// State filters pull requests based on their state. Possible values are:
+	// open, closed, all. Default is "open".
+	State string `url:"state,omitempty"`
+
+	// Head filters pull requests by head user and branch name in the format of:
+	// "user:ref-name".
+	Head string `url:"head,omitempty"`
+
+	// Base filters pull requests by base branch name.
+	Base string `url:"base,omitempty"`
+
+	// Sort specifies how to sort pull requests. Possible values are: created,
+	// updated, popularity, long-running. Default is "created".
+	Sort string `url:"sort,omitempty"`
+
+	// Direction in which to sort pull requests. Possible values are: asc, desc.
+	// If Sort is "created" or not specified, Default is "desc", otherwise Default
+	// is "asc"
+	Direction string `url:"direction,omitempty"`
+
+	ListOptions
+}
+
+// List the pull requests for the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/#list-pull-requests
+func (s *PullRequestsService) List(ctx context.Context, owner string, repo string, opt *PullRequestListOptions) ([]*PullRequest, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	acceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview, mediaTypeDraftPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	var pulls []*PullRequest
+	resp, err := s.client.Do(ctx, req, &pulls)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return pulls, resp, nil
+}
+
+// Get a single pull request.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/#get-a-single-pull-request
+func (s *PullRequestsService) Get(ctx context.Context, owner string, repo string, number int) (*PullRequest, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d", owner, repo, number)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	acceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview, mediaTypeDraftPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	pull := new(PullRequest)
+	resp, err := s.client.Do(ctx, req, pull)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return pull, resp, nil
+}
+
+// GetRaw gets a single pull request in raw (diff or patch) format.
+func (s *PullRequestsService) GetRaw(ctx context.Context, owner string, repo string, number int, opt RawOptions) (string, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d", owner, repo, number)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return "", nil, err
+	}
+
+	switch opt.Type {
+	case Diff:
+		req.Header.Set("Accept", mediaTypeV3Diff)
+	case Patch:
+		req.Header.Set("Accept", mediaTypeV3Patch)
+	default:
+		return "", nil, fmt.Errorf("unsupported raw type %d", opt.Type)
+	}
+
+	var buf bytes.Buffer
+	resp, err := s.client.Do(ctx, req, &buf)
+	if err != nil {
+		return "", resp, err
+	}
+
+	return buf.String(), resp, nil
+}
+
+// NewPullRequest represents a new pull request to be created.
+type NewPullRequest struct {
+	Title               *string `json:"title,omitempty"`
+	Head                *string `json:"head,omitempty"`
+	Base                *string `json:"base,omitempty"`
+	Body                *string `json:"body,omitempty"`
+	Issue               *int    `json:"issue,omitempty"`
+	MaintainerCanModify *bool   `json:"maintainer_can_modify,omitempty"`
+}
+
+// Create a new pull request on the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/#create-a-pull-request
+func (s *PullRequestsService) Create(ctx context.Context, owner string, repo string, pull *NewPullRequest) (*PullRequest, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls", owner, repo)
+	req, err := s.client.NewRequest("POST", u, pull)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
+
+	p := new(PullRequest)
+	resp, err := s.client.Do(ctx, req, p)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return p, resp, nil
+}
+
+type pullRequestUpdate struct {
+	Title               *string `json:"title,omitempty"`
+	Body                *string `json:"body,omitempty"`
+	State               *string `json:"state,omitempty"`
+	Base                *string `json:"base,omitempty"`
+	MaintainerCanModify *bool   `json:"maintainer_can_modify,omitempty"`
+}
+
+// Edit a pull request.
+// pull must not be nil.
+//
+// The following fields are editable: Title, Body, State, Base.Ref and MaintainerCanModify.
+// Base.Ref updates the base branch of the pull request.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/#update-a-pull-request
+func (s *PullRequestsService) Edit(ctx context.Context, owner string, repo string, number int, pull *PullRequest) (*PullRequest, *Response, error) {
+	if pull == nil {
+		return nil, nil, fmt.Errorf("pull must be provided")
+	}
+
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d", owner, repo, number)
+
+	update := &pullRequestUpdate{
+		Title:               pull.Title,
+		Body:                pull.Body,
+		State:               pull.State,
+		MaintainerCanModify: pull.MaintainerCanModify,
+	}
+	if pull.Base != nil {
+		update.Base = pull.Base.Ref
+	}
+
+	req, err := s.client.NewRequest("PATCH", u, update)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	acceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	p := new(PullRequest)
+	resp, err := s.client.Do(ctx, req, p)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return p, resp, nil
+}
+
+// ListCommits lists the commits in a pull request.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/#list-commits-on-a-pull-request
+func (s *PullRequestsService) ListCommits(ctx context.Context, owner string, repo string, number int, opt *ListOptions) ([]*RepositoryCommit, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d/commits", owner, repo, number)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var commits []*RepositoryCommit
+	resp, err := s.client.Do(ctx, req, &commits)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return commits, resp, nil
+}
+
+// ListFiles lists the files in a pull request.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/#list-pull-requests-files
+func (s *PullRequestsService) ListFiles(ctx context.Context, owner string, repo string, number int, opt *ListOptions) ([]*CommitFile, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d/files", owner, repo, number)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var commitFiles []*CommitFile
+	resp, err := s.client.Do(ctx, req, &commitFiles)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return commitFiles, resp, nil
+}
+
+// IsMerged checks if a pull request has been merged.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/#get-if-a-pull-request-has-been-merged
+func (s *PullRequestsService) IsMerged(ctx context.Context, owner string, repo string, number int) (bool, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d/merge", owner, repo, number)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return false, nil, err
+	}
+
+	resp, err := s.client.Do(ctx, req, nil)
+	merged, err := parseBoolResponse(err)
+	return merged, resp, err
+}
+
+// PullRequestMergeResult represents the result of merging a pull request.
+type PullRequestMergeResult struct {
+	SHA     *string `json:"sha,omitempty"`
+	Merged  *bool   `json:"merged,omitempty"`
+	Message *string `json:"message,omitempty"`
+}
+
+// PullRequestOptions lets you define how a pull request will be merged.
+type PullRequestOptions struct {
+	CommitTitle string // Extra detail to append to automatic commit message. (Optional.)
+	SHA         string // SHA that pull request head must match to allow merge. (Optional.)
+
+	// The merge method to use. Possible values include: "merge", "squash", and "rebase" with the default being merge. (Optional.)
+	MergeMethod string
+}
+
+type pullRequestMergeRequest struct {
+	CommitMessage string `json:"commit_message"`
+	CommitTitle   string `json:"commit_title,omitempty"`
+	MergeMethod   string `json:"merge_method,omitempty"`
+	SHA           string `json:"sha,omitempty"`
+}
+
+// Merge a pull request (Merge Buttonâ„¢).
+// commitMessage is the title for the automatic commit message.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/#merge-a-pull-request-merge-buttontrade
+func (s *PullRequestsService) Merge(ctx context.Context, owner string, repo string, number int, commitMessage string, options *PullRequestOptions) (*PullRequestMergeResult, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d/merge", owner, repo, number)
+
+	pullRequestBody := &pullRequestMergeRequest{CommitMessage: commitMessage}
+	if options != nil {
+		pullRequestBody.CommitTitle = options.CommitTitle
+		pullRequestBody.MergeMethod = options.MergeMethod
+		pullRequestBody.SHA = options.SHA
+	}
+	req, err := s.client.NewRequest("PUT", u, pullRequestBody)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	mergeResult := new(PullRequestMergeResult)
+	resp, err := s.client.Do(ctx, req, mergeResult)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return mergeResult, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/pulls_comments.go b/vendor/github.com/google/go-github/v24/github/pulls_comments.go
new file mode 100644
index 000000000..f30677625
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/pulls_comments.go
@@ -0,0 +1,188 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// PullRequestComment represents a comment left on a pull request.
+type PullRequestComment struct {
+	ID                  *int64     `json:"id,omitempty"`
+	InReplyTo           *int64     `json:"in_reply_to_id,omitempty"`
+	Body                *string    `json:"body,omitempty"`
+	Path                *string    `json:"path,omitempty"`
+	DiffHunk            *string    `json:"diff_hunk,omitempty"`
+	PullRequestReviewID *int64     `json:"pull_request_review_id,omitempty"`
+	Position            *int       `json:"position,omitempty"`
+	OriginalPosition    *int       `json:"original_position,omitempty"`
+	CommitID            *string    `json:"commit_id,omitempty"`
+	OriginalCommitID    *string    `json:"original_commit_id,omitempty"`
+	User                *User      `json:"user,omitempty"`
+	Reactions           *Reactions `json:"reactions,omitempty"`
+	CreatedAt           *time.Time `json:"created_at,omitempty"`
+	UpdatedAt           *time.Time `json:"updated_at,omitempty"`
+	// AuthorAssociation is the comment author's relationship to the pull request's repository.
+	// Possible values are "COLLABORATOR", "CONTRIBUTOR", "FIRST_TIMER", "FIRST_TIME_CONTRIBUTOR", "MEMBER", "OWNER", or "NONE".
+	AuthorAssociation *string `json:"author_association,omitempty"`
+	URL               *string `json:"url,omitempty"`
+	HTMLURL           *string `json:"html_url,omitempty"`
+	PullRequestURL    *string `json:"pull_request_url,omitempty"`
+}
+
+func (p PullRequestComment) String() string {
+	return Stringify(p)
+}
+
+// PullRequestListCommentsOptions specifies the optional parameters to the
+// PullRequestsService.ListComments method.
+type PullRequestListCommentsOptions struct {
+	// Sort specifies how to sort comments. Possible values are: created, updated.
+	Sort string `url:"sort,omitempty"`
+
+	// Direction in which to sort comments. Possible values are: asc, desc.
+	Direction string `url:"direction,omitempty"`
+
+	// Since filters comments by time.
+	Since time.Time `url:"since,omitempty"`
+
+	ListOptions
+}
+
+// ListComments lists all comments on the specified pull request. Specifying a
+// pull request number of 0 will return all comments on all pull requests for
+// the repository.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/comments/#list-comments-on-a-pull-request
+func (s *PullRequestsService) ListComments(ctx context.Context, owner string, repo string, number int, opt *PullRequestListCommentsOptions) ([]*PullRequestComment, *Response, error) {
+	var u string
+	if number == 0 {
+		u = fmt.Sprintf("repos/%v/%v/pulls/comments", owner, repo)
+	} else {
+		u = fmt.Sprintf("repos/%v/%v/pulls/%d/comments", owner, repo, number)
+	}
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	var comments []*PullRequestComment
+	resp, err := s.client.Do(ctx, req, &comments)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return comments, resp, nil
+}
+
+// GetComment fetches the specified pull request comment.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/comments/#get-a-single-comment
+func (s *PullRequestsService) GetComment(ctx context.Context, owner string, repo string, commentID int64) (*PullRequestComment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/comments/%d", owner, repo, commentID)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	comment := new(PullRequestComment)
+	resp, err := s.client.Do(ctx, req, comment)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return comment, resp, nil
+}
+
+// CreateComment creates a new comment on the specified pull request.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/comments/#create-a-comment
+func (s *PullRequestsService) CreateComment(ctx context.Context, owner string, repo string, number int, comment *PullRequestComment) (*PullRequestComment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d/comments", owner, repo, number)
+	req, err := s.client.NewRequest("POST", u, comment)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	c := new(PullRequestComment)
+	resp, err := s.client.Do(ctx, req, c)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return c, resp, nil
+}
+
+// CreateCommentInReplyTo creates a new comment as a reply to an existing pull request comment.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/comments/#alternative-input
+func (s *PullRequestsService) CreateCommentInReplyTo(ctx context.Context, owner string, repo string, number int, body string, commentID int64) (*PullRequestComment, *Response, error) {
+	comment := &struct {
+		Body      string `json:"body,omitempty"`
+		InReplyTo int64  `json:"in_reply_to,omitempty"`
+	}{
+		Body:      body,
+		InReplyTo: commentID,
+	}
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d/comments", owner, repo, number)
+	req, err := s.client.NewRequest("POST", u, comment)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	c := new(PullRequestComment)
+	resp, err := s.client.Do(ctx, req, c)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return c, resp, nil
+}
+
+// EditComment updates a pull request comment.
+// A non-nil comment.Body must be provided. Other comment fields should be left nil.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/comments/#edit-a-comment
+func (s *PullRequestsService) EditComment(ctx context.Context, owner string, repo string, commentID int64, comment *PullRequestComment) (*PullRequestComment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/comments/%d", owner, repo, commentID)
+	req, err := s.client.NewRequest("PATCH", u, comment)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	c := new(PullRequestComment)
+	resp, err := s.client.Do(ctx, req, c)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return c, resp, nil
+}
+
+// DeleteComment deletes a pull request comment.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/comments/#delete-a-comment
+func (s *PullRequestsService) DeleteComment(ctx context.Context, owner string, repo string, commentID int64) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/comments/%d", owner, repo, commentID)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/pulls_reviewers.go b/vendor/github.com/google/go-github/v24/github/pulls_reviewers.go
new file mode 100644
index 000000000..a1d785315
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/pulls_reviewers.go
@@ -0,0 +1,79 @@
+// Copyright 2017 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// ReviewersRequest specifies users and teams for a pull request review request.
+type ReviewersRequest struct {
+	Reviewers     []string `json:"reviewers,omitempty"`
+	TeamReviewers []string `json:"team_reviewers,omitempty"`
+}
+
+// Reviewers represents reviewers of a pull request.
+type Reviewers struct {
+	Users []*User `json:"users,omitempty"`
+	Teams []*Team `json:"teams,omitempty"`
+}
+
+// RequestReviewers creates a review request for the provided reviewers for the specified pull request.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/review_requests/#create-a-review-request
+func (s *PullRequestsService) RequestReviewers(ctx context.Context, owner, repo string, number int, reviewers ReviewersRequest) (*PullRequest, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/pulls/%d/requested_reviewers", owner, repo, number)
+	req, err := s.client.NewRequest("POST", u, &reviewers)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	r := new(PullRequest)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
+
+// ListReviewers lists reviewers whose reviews have been requested on the specified pull request.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/review_requests/#list-review-requests
+func (s *PullRequestsService) ListReviewers(ctx context.Context, owner, repo string, number int, opt *ListOptions) (*Reviewers, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d/requested_reviewers", owner, repo, number)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	reviewers := new(Reviewers)
+	resp, err := s.client.Do(ctx, req, reviewers)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return reviewers, resp, nil
+}
+
+// RemoveReviewers removes the review request for the provided reviewers for the specified pull request.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/review_requests/#delete-a-review-request
+func (s *PullRequestsService) RemoveReviewers(ctx context.Context, owner, repo string, number int, reviewers ReviewersRequest) (*Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/pulls/%d/requested_reviewers", owner, repo, number)
+	req, err := s.client.NewRequest("DELETE", u, &reviewers)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/pulls_reviews.go b/vendor/github.com/google/go-github/v24/github/pulls_reviews.go
new file mode 100644
index 000000000..57d3c635e
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/pulls_reviews.go
@@ -0,0 +1,236 @@
+// Copyright 2016 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// PullRequestReview represents a review of a pull request.
+type PullRequestReview struct {
+	ID             *int64     `json:"id,omitempty"`
+	User           *User      `json:"user,omitempty"`
+	Body           *string    `json:"body,omitempty"`
+	SubmittedAt    *time.Time `json:"submitted_at,omitempty"`
+	CommitID       *string    `json:"commit_id,omitempty"`
+	HTMLURL        *string    `json:"html_url,omitempty"`
+	PullRequestURL *string    `json:"pull_request_url,omitempty"`
+	State          *string    `json:"state,omitempty"`
+}
+
+func (p PullRequestReview) String() string {
+	return Stringify(p)
+}
+
+// DraftReviewComment represents a comment part of the review.
+type DraftReviewComment struct {
+	Path     *string `json:"path,omitempty"`
+	Position *int    `json:"position,omitempty"`
+	Body     *string `json:"body,omitempty"`
+}
+
+func (c DraftReviewComment) String() string {
+	return Stringify(c)
+}
+
+// PullRequestReviewRequest represents a request to create a review.
+type PullRequestReviewRequest struct {
+	CommitID *string               `json:"commit_id,omitempty"`
+	Body     *string               `json:"body,omitempty"`
+	Event    *string               `json:"event,omitempty"`
+	Comments []*DraftReviewComment `json:"comments,omitempty"`
+}
+
+func (r PullRequestReviewRequest) String() string {
+	return Stringify(r)
+}
+
+// PullRequestReviewDismissalRequest represents a request to dismiss a review.
+type PullRequestReviewDismissalRequest struct {
+	Message *string `json:"message,omitempty"`
+}
+
+func (r PullRequestReviewDismissalRequest) String() string {
+	return Stringify(r)
+}
+
+// ListReviews lists all reviews on the specified pull request.
+//
+// TODO: Follow up with GitHub support about an issue with this method's
+// returned error format and remove this comment once it's fixed.
+// Read more about it here - https://github.com/google/go-github/issues/540
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#list-reviews-on-a-pull-request
+func (s *PullRequestsService) ListReviews(ctx context.Context, owner, repo string, number int, opt *ListOptions) ([]*PullRequestReview, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews", owner, repo, number)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var reviews []*PullRequestReview
+	resp, err := s.client.Do(ctx, req, &reviews)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return reviews, resp, nil
+}
+
+// GetReview fetches the specified pull request review.
+//
+// TODO: Follow up with GitHub support about an issue with this method's
+// returned error format and remove this comment once it's fixed.
+// Read more about it here - https://github.com/google/go-github/issues/540
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#get-a-single-review
+func (s *PullRequestsService) GetReview(ctx context.Context, owner, repo string, number int, reviewID int64) (*PullRequestReview, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d", owner, repo, number, reviewID)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	review := new(PullRequestReview)
+	resp, err := s.client.Do(ctx, req, review)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return review, resp, nil
+}
+
+// DeletePendingReview deletes the specified pull request pending review.
+//
+// TODO: Follow up with GitHub support about an issue with this method's
+// returned error format and remove this comment once it's fixed.
+// Read more about it here - https://github.com/google/go-github/issues/540
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#delete-a-pending-review
+func (s *PullRequestsService) DeletePendingReview(ctx context.Context, owner, repo string, number int, reviewID int64) (*PullRequestReview, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d", owner, repo, number, reviewID)
+
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	review := new(PullRequestReview)
+	resp, err := s.client.Do(ctx, req, review)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return review, resp, nil
+}
+
+// ListReviewComments lists all the comments for the specified review.
+//
+// TODO: Follow up with GitHub support about an issue with this method's
+// returned error format and remove this comment once it's fixed.
+// Read more about it here - https://github.com/google/go-github/issues/540
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#get-comments-for-a-single-review
+func (s *PullRequestsService) ListReviewComments(ctx context.Context, owner, repo string, number int, reviewID int64, opt *ListOptions) ([]*PullRequestComment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d/comments", owner, repo, number, reviewID)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var comments []*PullRequestComment
+	resp, err := s.client.Do(ctx, req, &comments)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return comments, resp, nil
+}
+
+// CreateReview creates a new review on the specified pull request.
+//
+// TODO: Follow up with GitHub support about an issue with this method's
+// returned error format and remove this comment once it's fixed.
+// Read more about it here - https://github.com/google/go-github/issues/540
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#create-a-pull-request-review
+func (s *PullRequestsService) CreateReview(ctx context.Context, owner, repo string, number int, review *PullRequestReviewRequest) (*PullRequestReview, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews", owner, repo, number)
+
+	req, err := s.client.NewRequest("POST", u, review)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	r := new(PullRequestReview)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
+
+// SubmitReview submits a specified review on the specified pull request.
+//
+// TODO: Follow up with GitHub support about an issue with this method's
+// returned error format and remove this comment once it's fixed.
+// Read more about it here - https://github.com/google/go-github/issues/540
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#submit-a-pull-request-review
+func (s *PullRequestsService) SubmitReview(ctx context.Context, owner, repo string, number int, reviewID int64, review *PullRequestReviewRequest) (*PullRequestReview, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d/events", owner, repo, number, reviewID)
+
+	req, err := s.client.NewRequest("POST", u, review)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	r := new(PullRequestReview)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
+
+// DismissReview dismisses a specified review on the specified pull request.
+//
+// TODO: Follow up with GitHub support about an issue with this method's
+// returned error format and remove this comment once it's fixed.
+// Read more about it here - https://github.com/google/go-github/issues/540
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#dismiss-a-pull-request-review
+func (s *PullRequestsService) DismissReview(ctx context.Context, owner, repo string, number int, reviewID int64, review *PullRequestReviewDismissalRequest) (*PullRequestReview, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d/dismissals", owner, repo, number, reviewID)
+
+	req, err := s.client.NewRequest("PUT", u, review)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	r := new(PullRequestReview)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/reactions.go b/vendor/github.com/google/go-github/v24/github/reactions.go
new file mode 100644
index 000000000..0865f8cdc
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/reactions.go
@@ -0,0 +1,377 @@
+// Copyright 2016 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// ReactionsService provides access to the reactions-related functions in the
+// GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/reactions/
+type ReactionsService service
+
+// Reaction represents a GitHub reaction.
+type Reaction struct {
+	// ID is the Reaction ID.
+	ID     *int64  `json:"id,omitempty"`
+	User   *User   `json:"user,omitempty"`
+	NodeID *string `json:"node_id,omitempty"`
+	// Content is the type of reaction.
+	// Possible values are:
+	//     "+1", "-1", "laugh", "confused", "heart", "hooray".
+	Content *string `json:"content,omitempty"`
+}
+
+// Reactions represents a summary of GitHub reactions.
+type Reactions struct {
+	TotalCount *int    `json:"total_count,omitempty"`
+	PlusOne    *int    `json:"+1,omitempty"`
+	MinusOne   *int    `json:"-1,omitempty"`
+	Laugh      *int    `json:"laugh,omitempty"`
+	Confused   *int    `json:"confused,omitempty"`
+	Heart      *int    `json:"heart,omitempty"`
+	Hooray     *int    `json:"hooray,omitempty"`
+	URL        *string `json:"url,omitempty"`
+}
+
+func (r Reaction) String() string {
+	return Stringify(r)
+}
+
+// ListCommentReactions lists the reactions for a commit comment.
+//
+// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-commit-comment
+func (s *ReactionsService) ListCommentReactions(ctx context.Context, owner, repo string, id int64, opt *ListOptions) ([]*Reaction, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/comments/%v/reactions", owner, repo, id)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	var m []*Reaction
+	resp, err := s.client.Do(ctx, req, &m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// CreateCommentReaction creates a reaction for a commit comment.
+// Note that if you have already created a reaction of type content, the
+// previously created reaction will be returned with Status: 200 OK.
+// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray".
+//
+// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-commit-comment
+func (s ReactionsService) CreateCommentReaction(ctx context.Context, owner, repo string, id int64, content string) (*Reaction, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/comments/%v/reactions", owner, repo, id)
+
+	body := &Reaction{Content: String(content)}
+	req, err := s.client.NewRequest("POST", u, body)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	m := &Reaction{}
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// ListIssueReactions lists the reactions for an issue.
+//
+// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-an-issue
+func (s *ReactionsService) ListIssueReactions(ctx context.Context, owner, repo string, number int, opt *ListOptions) ([]*Reaction, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%v/reactions", owner, repo, number)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	var m []*Reaction
+	resp, err := s.client.Do(ctx, req, &m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// CreateIssueReaction creates a reaction for an issue.
+// Note that if you have already created a reaction of type content, the
+// previously created reaction will be returned with Status: 200 OK.
+// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray".
+//
+// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-an-issue
+func (s ReactionsService) CreateIssueReaction(ctx context.Context, owner, repo string, number int, content string) (*Reaction, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%v/reactions", owner, repo, number)
+
+	body := &Reaction{Content: String(content)}
+	req, err := s.client.NewRequest("POST", u, body)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	m := &Reaction{}
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// ListIssueCommentReactions lists the reactions for an issue comment.
+//
+// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-an-issue-comment
+func (s *ReactionsService) ListIssueCommentReactions(ctx context.Context, owner, repo string, id int64, opt *ListOptions) ([]*Reaction, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/comments/%v/reactions", owner, repo, id)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	var m []*Reaction
+	resp, err := s.client.Do(ctx, req, &m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// CreateIssueCommentReaction creates a reaction for an issue comment.
+// Note that if you have already created a reaction of type content, the
+// previously created reaction will be returned with Status: 200 OK.
+// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray".
+//
+// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-an-issue-comment
+func (s ReactionsService) CreateIssueCommentReaction(ctx context.Context, owner, repo string, id int64, content string) (*Reaction, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/comments/%v/reactions", owner, repo, id)
+
+	body := &Reaction{Content: String(content)}
+	req, err := s.client.NewRequest("POST", u, body)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	m := &Reaction{}
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// ListPullRequestCommentReactions lists the reactions for a pull request review comment.
+//
+// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-an-issue-comment
+func (s *ReactionsService) ListPullRequestCommentReactions(ctx context.Context, owner, repo string, id int64, opt *ListOptions) ([]*Reaction, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/comments/%v/reactions", owner, repo, id)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	var m []*Reaction
+	resp, err := s.client.Do(ctx, req, &m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// CreatePullRequestCommentReaction creates a reaction for a pull request review comment.
+// Note that if you have already created a reaction of type content, the
+// previously created reaction will be returned with Status: 200 OK.
+// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray".
+//
+// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-an-issue-comment
+func (s ReactionsService) CreatePullRequestCommentReaction(ctx context.Context, owner, repo string, id int64, content string) (*Reaction, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/comments/%v/reactions", owner, repo, id)
+
+	body := &Reaction{Content: String(content)}
+	req, err := s.client.NewRequest("POST", u, body)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	m := &Reaction{}
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// ListTeamDiscussionReactions lists the reactions for a team discussion.
+//
+// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-team-discussion
+func (s *ReactionsService) ListTeamDiscussionReactions(ctx context.Context, teamID int64, discussionNumber int, opt *ListOptions) ([]*Reaction, *Response, error) {
+	u := fmt.Sprintf("teams/%v/discussions/%v/reactions", teamID, discussionNumber)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	var m []*Reaction
+	resp, err := s.client.Do(ctx, req, &m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// CreateTeamDiscussionReaction creates a reaction for a team discussion.
+// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray".
+//
+// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-team-discussion
+func (s *ReactionsService) CreateTeamDiscussionReaction(ctx context.Context, teamID int64, discussionNumber int, content string) (*Reaction, *Response, error) {
+	u := fmt.Sprintf("teams/%v/discussions/%v/reactions", teamID, discussionNumber)
+
+	body := &Reaction{Content: String(content)}
+	req, err := s.client.NewRequest("POST", u, body)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	m := &Reaction{}
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// ListTeamDiscussionCommentReactions lists the reactions for a team discussion comment.
+//
+// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-team-discussion-comment
+func (s *ReactionsService) ListTeamDiscussionCommentReactions(ctx context.Context, teamID int64, discussionNumber, commentNumber int, opt *ListOptions) ([]*Reaction, *Response, error) {
+	u := fmt.Sprintf("teams/%v/discussions/%v/comments/%v/reactions", teamID, discussionNumber, commentNumber)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	var m []*Reaction
+	resp, err := s.client.Do(ctx, req, &m)
+	if err != nil {
+		return nil, nil, err
+	}
+	return m, resp, nil
+}
+
+// CreateTeamDiscussionCommentReaction creates a reaction for a team discussion comment.
+// The content should have one of the following values: "+1", "-1", "laugh", "confused", "heart", "hooray".
+//
+// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-team-discussion-comment
+func (s *ReactionsService) CreateTeamDiscussionCommentReaction(ctx context.Context, teamID int64, discussionNumber, commentNumber int, content string) (*Reaction, *Response, error) {
+	u := fmt.Sprintf("teams/%v/discussions/%v/comments/%v/reactions", teamID, discussionNumber, commentNumber)
+
+	body := &Reaction{Content: String(content)}
+	req, err := s.client.NewRequest("POST", u, body)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	m := &Reaction{}
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// DeleteReaction deletes a reaction.
+//
+// GitHub API docs: https://developer.github.com/v3/reaction/reactions/#delete-a-reaction-archive
+func (s *ReactionsService) DeleteReaction(ctx context.Context, id int64) (*Response, error) {
+	u := fmt.Sprintf("reactions/%v", id)
+
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/repos.go b/vendor/github.com/google/go-github/v24/github/repos.go
new file mode 100644
index 000000000..617c20db5
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/repos.go
@@ -0,0 +1,1197 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"strings"
+)
+
+// RepositoriesService handles communication with the repository related
+// methods of the GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/
+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"`
+	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"`
+
+	// Only provided when using RepositoriesService.Get while in preview
+	License *License `json:"license,omitempty"`
+
+	// Additional mutable fields when creating and editing a repository
+	Private           *bool   `json:"private,omitempty"`
+	HasIssues         *bool   `json:"has_issues,omitempty"`
+	HasWiki           *bool   `json:"has_wiki,omitempty"`
+	HasPages          *bool   `json:"has_pages,omitempty"`
+	HasProjects       *bool   `json:"has_projects,omitempty"`
+	HasDownloads      *bool   `json:"has_downloads,omitempty"`
+	LicenseTemplate   *string `json:"license_template,omitempty"`
+	GitignoreTemplate *string `json:"gitignore_template,omitempty"`
+
+	// Creating an organization repository. Required for non-owners.
+	TeamID *int64 `json:"team_id,omitempty"`
+
+	// API URLs
+	URL              *string `json:"url,omitempty"`
+	ArchiveURL       *string `json:"archive_url,omitempty"`
+	AssigneesURL     *string `json:"assignees_url,omitempty"`
+	BlobsURL         *string `json:"blobs_url,omitempty"`
+	BranchesURL      *string `json:"branches_url,omitempty"`
+	CollaboratorsURL *string `json:"collaborators_url,omitempty"`
+	CommentsURL      *string `json:"comments_url,omitempty"`
+	CommitsURL       *string `json:"commits_url,omitempty"`
+	CompareURL       *string `json:"compare_url,omitempty"`
+	ContentsURL      *string `json:"contents_url,omitempty"`
+	ContributorsURL  *string `json:"contributors_url,omitempty"`
+	DeploymentsURL   *string `json:"deployments_url,omitempty"`
+	DownloadsURL     *string `json:"downloads_url,omitempty"`
+	EventsURL        *string `json:"events_url,omitempty"`
+	ForksURL         *string `json:"forks_url,omitempty"`
+	GitCommitsURL    *string `json:"git_commits_url,omitempty"`
+	GitRefsURL       *string `json:"git_refs_url,omitempty"`
+	GitTagsURL       *string `json:"git_tags_url,omitempty"`
+	HooksURL         *string `json:"hooks_url,omitempty"`
+	IssueCommentURL  *string `json:"issue_comment_url,omitempty"`
+	IssueEventsURL   *string `json:"issue_events_url,omitempty"`
+	IssuesURL        *string `json:"issues_url,omitempty"`
+	KeysURL          *string `json:"keys_url,omitempty"`
+	LabelsURL        *string `json:"labels_url,omitempty"`
+	LanguagesURL     *string `json:"languages_url,omitempty"`
+	MergesURL        *string `json:"merges_url,omitempty"`
+	MilestonesURL    *string `json:"milestones_url,omitempty"`
+	NotificationsURL *string `json:"notifications_url,omitempty"`
+	PullsURL         *string `json:"pulls_url,omitempty"`
+	ReleasesURL      *string `json:"releases_url,omitempty"`
+	StargazersURL    *string `json:"stargazers_url,omitempty"`
+	StatusesURL      *string `json:"statuses_url,omitempty"`
+	SubscribersURL   *string `json:"subscribers_url,omitempty"`
+	SubscriptionURL  *string `json:"subscription_url,omitempty"`
+	TagsURL          *string `json:"tags_url,omitempty"`
+	TreesURL         *string `json:"trees_url,omitempty"`
+	TeamsURL         *string `json:"teams_url,omitempty"`
+
+	// TextMatches is only populated from search results that request text matches
+	// See: search.go and https://developer.github.com/v3/search/#text-match-metadata
+	TextMatches []TextMatch `json:"text_matches,omitempty"`
+}
+
+func (r Repository) String() string {
+	return Stringify(r)
+}
+
+// RepositoryListOptions specifies the optional parameters to the
+// RepositoriesService.List method.
+type RepositoryListOptions struct {
+	// Visibility of repositories to list. Can be one of all, public, or private.
+	// Default: all
+	Visibility string `url:"visibility,omitempty"`
+
+	// List repos of given affiliation[s].
+	// Comma-separated list of values. Can include:
+	// * owner: Repositories that are owned by the authenticated user.
+	// * collaborator: Repositories that the user has been added to as a
+	//   collaborator.
+	// * organization_member: Repositories that the user has access to through
+	//   being a member of an organization. This includes every repository on
+	//   every team that the user is on.
+	// Default: owner,collaborator,organization_member
+	Affiliation string `url:"affiliation,omitempty"`
+
+	// Type of repositories to list.
+	// Can be one of all, owner, public, private, member. Default: all
+	// Will cause a 422 error if used in the same request as visibility or
+	// affiliation.
+	Type string `url:"type,omitempty"`
+
+	// How to sort the repository list. Can be one of created, updated, pushed,
+	// full_name. Default: full_name
+	Sort string `url:"sort,omitempty"`
+
+	// Direction in which to sort repositories. Can be one of asc or desc.
+	// Default: when using full_name: asc; otherwise desc
+	Direction string `url:"direction,omitempty"`
+
+	ListOptions
+}
+
+// List the repositories for a user. Passing the empty string will list
+// repositories for the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#list-user-repositories
+func (s *RepositoriesService) List(ctx context.Context, user string, opt *RepositoryListOptions) ([]*Repository, *Response, error) {
+	var u string
+	if user != "" {
+		u = fmt.Sprintf("users/%v/repos", user)
+	} else {
+		u = "user/repos"
+	}
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeTopicsPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	var repos []*Repository
+	resp, err := s.client.Do(ctx, req, &repos)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return repos, resp, nil
+}
+
+// RepositoryListByOrgOptions specifies the optional parameters to the
+// RepositoriesService.ListByOrg method.
+type RepositoryListByOrgOptions struct {
+	// Type of repositories to list. Possible values are: all, public, private,
+	// forks, sources, member. Default is "all".
+	Type string `url:"type,omitempty"`
+
+	ListOptions
+}
+
+// ListByOrg lists the repositories for an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#list-organization-repositories
+func (s *RepositoriesService) ListByOrg(ctx context.Context, org string, opt *RepositoryListByOrgOptions) ([]*Repository, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/repos", org)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeTopicsPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	var repos []*Repository
+	resp, err := s.client.Do(ctx, req, &repos)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return repos, resp, nil
+}
+
+// RepositoryListAllOptions specifies the optional parameters to the
+// RepositoriesService.ListAll method.
+type RepositoryListAllOptions struct {
+	// ID of the last repository seen
+	Since int64 `url:"since,omitempty"`
+}
+
+// ListAll lists all GitHub repositories in the order that they were created.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#list-all-public-repositories
+func (s *RepositoriesService) ListAll(ctx context.Context, opt *RepositoryListAllOptions) ([]*Repository, *Response, error) {
+	u, err := addOptions("repositories", opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var repos []*Repository
+	resp, err := s.client.Do(ctx, req, &repos)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return repos, resp, nil
+}
+
+// createRepoRequest is a subset of Repository and is used internally
+// by Create to pass only the known fields for the endpoint.
+//
+// See https://github.com/google/go-github/issues/1014 for more
+// information.
+type createRepoRequest struct {
+	// Name is required when creating a repo.
+	Name        *string `json:"name,omitempty"`
+	Description *string `json:"description,omitempty"`
+	Homepage    *string `json:"homepage,omitempty"`
+
+	Private     *bool `json:"private,omitempty"`
+	HasIssues   *bool `json:"has_issues,omitempty"`
+	HasProjects *bool `json:"has_projects,omitempty"`
+	HasWiki     *bool `json:"has_wiki,omitempty"`
+
+	// 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"`
+}
+
+// Create a new repository. If an organization is specified, the new
+// repository will be created under that org. If the empty string is
+// specified, it will be created for the authenticated user.
+//
+// Note that only a subset of the repo fields are used and repo must
+// not be nil.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#create
+func (s *RepositoriesService) Create(ctx context.Context, org string, repo *Repository) (*Repository, *Response, error) {
+	var u string
+	if org != "" {
+		u = fmt.Sprintf("orgs/%v/repos", org)
+	} else {
+		u = "user/repos"
+	}
+
+	repoReq := &createRepoRequest{
+		Name:              repo.Name,
+		Description:       repo.Description,
+		Homepage:          repo.Homepage,
+		Private:           repo.Private,
+		HasIssues:         repo.HasIssues,
+		HasProjects:       repo.HasProjects,
+		HasWiki:           repo.HasWiki,
+		TeamID:            repo.TeamID,
+		AutoInit:          repo.AutoInit,
+		GitignoreTemplate: repo.GitignoreTemplate,
+		LicenseTemplate:   repo.LicenseTemplate,
+		AllowSquashMerge:  repo.AllowSquashMerge,
+		AllowMergeCommit:  repo.AllowMergeCommit,
+		AllowRebaseMerge:  repo.AllowRebaseMerge,
+	}
+
+	req, err := s.client.NewRequest("POST", u, repoReq)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	r := new(Repository)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
+
+// Get fetches a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#get
+func (s *RepositoriesService) Get(ctx context.Context, owner, repo string) (*Repository, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when the license support fully launches
+	// https://developer.github.com/v3/licenses/#get-a-repositorys-license
+	acceptHeaders := []string{mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	repository := new(Repository)
+	resp, err := s.client.Do(ctx, req, repository)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return repository, resp, nil
+}
+
+// GetCodeOfConduct gets the contents of a repository's code of conduct.
+//
+// GitHub API docs: https://developer.github.com/v3/codes_of_conduct/#get-the-contents-of-a-repositorys-code-of-conduct
+func (s *RepositoriesService) GetCodeOfConduct(ctx context.Context, owner, repo string) (*CodeOfConduct, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/community/code_of_conduct", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeCodesOfConductPreview)
+
+	coc := new(CodeOfConduct)
+	resp, err := s.client.Do(ctx, req, coc)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return coc, resp, nil
+}
+
+// GetByID fetches a repository.
+//
+// Note: GetByID uses the undocumented GitHub API endpoint /repositories/:id.
+func (s *RepositoriesService) GetByID(ctx context.Context, id int64) (*Repository, *Response, error) {
+	u := fmt.Sprintf("repositories/%d", id)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	repository := new(Repository)
+	resp, err := s.client.Do(ctx, req, repository)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return repository, resp, nil
+}
+
+// Edit updates a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#edit
+func (s *RepositoriesService) Edit(ctx context.Context, owner, repo string, repository *Repository) (*Repository, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v", owner, repo)
+	req, err := s.client.NewRequest("PATCH", u, repository)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	r := new(Repository)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
+
+// Delete a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#delete-a-repository
+func (s *RepositoriesService) Delete(ctx context.Context, owner, repo string) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v", owner, repo)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// Contributor represents a repository contributor
+type Contributor struct {
+	Login             *string `json:"login,omitempty"`
+	ID                *int64  `json:"id,omitempty"`
+	AvatarURL         *string `json:"avatar_url,omitempty"`
+	GravatarID        *string `json:"gravatar_id,omitempty"`
+	URL               *string `json:"url,omitempty"`
+	HTMLURL           *string `json:"html_url,omitempty"`
+	FollowersURL      *string `json:"followers_url,omitempty"`
+	FollowingURL      *string `json:"following_url,omitempty"`
+	GistsURL          *string `json:"gists_url,omitempty"`
+	StarredURL        *string `json:"starred_url,omitempty"`
+	SubscriptionsURL  *string `json:"subscriptions_url,omitempty"`
+	OrganizationsURL  *string `json:"organizations_url,omitempty"`
+	ReposURL          *string `json:"repos_url,omitempty"`
+	EventsURL         *string `json:"events_url,omitempty"`
+	ReceivedEventsURL *string `json:"received_events_url,omitempty"`
+	Type              *string `json:"type,omitempty"`
+	SiteAdmin         *bool   `json:"site_admin,omitempty"`
+	Contributions     *int    `json:"contributions,omitempty"`
+}
+
+// ListContributorsOptions specifies the optional parameters to the
+// RepositoriesService.ListContributors method.
+type ListContributorsOptions struct {
+	// Include anonymous contributors in results or not
+	Anon string `url:"anon,omitempty"`
+
+	ListOptions
+}
+
+// ListContributors lists contributors for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#list-contributors
+func (s *RepositoriesService) ListContributors(ctx context.Context, owner string, repository string, opt *ListContributorsOptions) ([]*Contributor, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/contributors", owner, repository)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var contributor []*Contributor
+	resp, err := s.client.Do(ctx, req, &contributor)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	return contributor, resp, nil
+}
+
+// ListLanguages lists languages for the specified repository. The returned map
+// specifies the languages and the number of bytes of code written in that
+// language. For example:
+//
+//     {
+//       "C": 78769,
+//       "Python": 7769
+//     }
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#list-languages
+func (s *RepositoriesService) ListLanguages(ctx context.Context, owner string, repo string) (map[string]int, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/languages", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	languages := make(map[string]int)
+	resp, err := s.client.Do(ctx, req, &languages)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return languages, resp, nil
+}
+
+// ListTeams lists the teams for the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#list-teams
+func (s *RepositoriesService) ListTeams(ctx context.Context, owner string, repo string, opt *ListOptions) ([]*Team, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/teams", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
+	var teams []*Team
+	resp, err := s.client.Do(ctx, req, &teams)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return teams, resp, nil
+}
+
+// RepositoryTag represents a repository tag.
+type RepositoryTag struct {
+	Name       *string `json:"name,omitempty"`
+	Commit     *Commit `json:"commit,omitempty"`
+	ZipballURL *string `json:"zipball_url,omitempty"`
+	TarballURL *string `json:"tarball_url,omitempty"`
+}
+
+// ListTags lists tags for the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#list-tags
+func (s *RepositoriesService) ListTags(ctx context.Context, owner string, repo string, opt *ListOptions) ([]*RepositoryTag, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/tags", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var tags []*RepositoryTag
+	resp, err := s.client.Do(ctx, req, &tags)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return tags, resp, nil
+}
+
+// Branch represents a repository branch
+type Branch struct {
+	Name      *string           `json:"name,omitempty"`
+	Commit    *RepositoryCommit `json:"commit,omitempty"`
+	Protected *bool             `json:"protected,omitempty"`
+}
+
+// Protection represents a repository branch's protection.
+type Protection struct {
+	RequiredStatusChecks       *RequiredStatusChecks          `json:"required_status_checks"`
+	RequiredPullRequestReviews *PullRequestReviewsEnforcement `json:"required_pull_request_reviews"`
+	EnforceAdmins              *AdminEnforcement              `json:"enforce_admins"`
+	Restrictions               *BranchRestrictions            `json:"restrictions"`
+}
+
+// ProtectionRequest represents a request to create/edit a branch's protection.
+type ProtectionRequest struct {
+	RequiredStatusChecks       *RequiredStatusChecks                 `json:"required_status_checks"`
+	RequiredPullRequestReviews *PullRequestReviewsEnforcementRequest `json:"required_pull_request_reviews"`
+	EnforceAdmins              bool                                  `json:"enforce_admins"`
+	Restrictions               *BranchRestrictionsRequest            `json:"restrictions"`
+}
+
+// RequiredStatusChecks represents the protection status of a individual branch.
+type RequiredStatusChecks struct {
+	// Require branches to be up to date before merging. (Required.)
+	Strict bool `json:"strict"`
+	// The list of status checks to require in order to merge into this
+	// branch. (Required; use []string{} instead of nil for empty list.)
+	Contexts []string `json:"contexts"`
+}
+
+// RequiredStatusChecksRequest represents a request to edit a protected branch's status checks.
+type RequiredStatusChecksRequest struct {
+	Strict   *bool    `json:"strict,omitempty"`
+	Contexts []string `json:"contexts,omitempty"`
+}
+
+// PullRequestReviewsEnforcement represents the pull request reviews enforcement of a protected branch.
+type PullRequestReviewsEnforcement struct {
+	// Specifies which users and teams can dismiss pull request reviews.
+	DismissalRestrictions DismissalRestrictions `json:"dismissal_restrictions"`
+	// Specifies if approved reviews are dismissed automatically, when a new commit is pushed.
+	DismissStaleReviews bool `json:"dismiss_stale_reviews"`
+	// RequireCodeOwnerReviews specifies if an approved review is required in pull requests including files with a designated code owner.
+	RequireCodeOwnerReviews bool `json:"require_code_owner_reviews"`
+	// RequiredApprovingReviewCount specifies the number of approvals required before the pull request can be merged.
+	// Valid values are 1-6.
+	RequiredApprovingReviewCount int `json:"required_approving_review_count"`
+}
+
+// PullRequestReviewsEnforcementRequest represents request to set the pull request review
+// enforcement of a protected branch. It is separate from PullRequestReviewsEnforcement above
+// because the request structure is different from the response structure.
+type PullRequestReviewsEnforcementRequest struct {
+	// Specifies which users and teams should be allowed to dismiss pull request reviews.
+	// User and team dismissal restrictions are only available for
+	// organization-owned repositories. Must be nil for personal repositories.
+	DismissalRestrictionsRequest *DismissalRestrictionsRequest `json:"dismissal_restrictions,omitempty"`
+	// Specifies if approved reviews can be dismissed automatically, when a new commit is pushed. (Required)
+	DismissStaleReviews bool `json:"dismiss_stale_reviews"`
+	// RequireCodeOwnerReviews specifies if an approved review is required in pull requests including files with a designated code owner.
+	RequireCodeOwnerReviews bool `json:"require_code_owner_reviews"`
+	// RequiredApprovingReviewCount specifies the number of approvals required before the pull request can be merged.
+	// Valid values are 1-6.
+	RequiredApprovingReviewCount int `json:"required_approving_review_count"`
+}
+
+// PullRequestReviewsEnforcementUpdate represents request to patch the pull request review
+// enforcement of a protected branch. It is separate from PullRequestReviewsEnforcementRequest above
+// because the patch request does not require all fields to be initialized.
+type PullRequestReviewsEnforcementUpdate struct {
+	// Specifies which users and teams can dismiss pull request reviews. Can be omitted.
+	DismissalRestrictionsRequest *DismissalRestrictionsRequest `json:"dismissal_restrictions,omitempty"`
+	// Specifies if approved reviews can be dismissed automatically, when a new commit is pushed. Can be omitted.
+	DismissStaleReviews *bool `json:"dismiss_stale_reviews,omitempty"`
+	// RequireCodeOwnerReviews specifies if an approved review is required in pull requests including files with a designated code owner.
+	RequireCodeOwnerReviews bool `json:"require_code_owner_reviews,omitempty"`
+	// RequiredApprovingReviewCount specifies the number of approvals required before the pull request can be merged.
+	// Valid values are 1 - 6.
+	RequiredApprovingReviewCount int `json:"required_approving_review_count"`
+}
+
+// AdminEnforcement represents the configuration to enforce required status checks for repository administrators.
+type AdminEnforcement struct {
+	URL     *string `json:"url,omitempty"`
+	Enabled bool    `json:"enabled"`
+}
+
+// BranchRestrictions represents the restriction that only certain users or
+// teams may push to a branch.
+type BranchRestrictions struct {
+	// The list of user logins with push access.
+	Users []*User `json:"users"`
+	// The list of team slugs with push access.
+	Teams []*Team `json:"teams"`
+}
+
+// BranchRestrictionsRequest represents the request to create/edit the
+// restriction that only certain users or teams may push to a branch. It is
+// separate from BranchRestrictions above because the request structure is
+// different from the response structure.
+type BranchRestrictionsRequest struct {
+	// The list of user logins with push access. (Required; use []string{} instead of nil for empty list.)
+	Users []string `json:"users"`
+	// The list of team slugs with push access. (Required; use []string{} instead of nil for empty list.)
+	Teams []string `json:"teams"`
+}
+
+// DismissalRestrictions specifies which users and teams can dismiss pull request reviews.
+type DismissalRestrictions struct {
+	// The list of users who can dimiss pull request reviews.
+	Users []*User `json:"users"`
+	// The list of teams which can dismiss pull request reviews.
+	Teams []*Team `json:"teams"`
+}
+
+// DismissalRestrictionsRequest represents the request to create/edit the
+// restriction to allows only specific users or teams to dimiss pull request reviews. It is
+// separate from DismissalRestrictions above because the request structure is
+// different from the response structure.
+// Note: Both Users and Teams must be nil, or both must be non-nil.
+type DismissalRestrictionsRequest struct {
+	// The list of user logins who can dismiss pull request reviews. (Required; use nil to disable dismissal_restrictions or &[]string{} otherwise.)
+	Users *[]string `json:"users,omitempty"`
+	// The list of team slugs which can dismiss pull request reviews. (Required; use nil to disable dismissal_restrictions or &[]string{} otherwise.)
+	Teams *[]string `json:"teams,omitempty"`
+}
+
+// SignaturesProtectedBranch represents the protection status of an individual branch.
+type SignaturesProtectedBranch struct {
+	URL *string `json:"url,omitempty"`
+	// Commits pushed to matching branches must have verified signatures.
+	Enabled *bool `json:"enabled,omitempty"`
+}
+
+// ListBranches lists branches for the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#list-branches
+func (s *RepositoriesService) ListBranches(ctx context.Context, owner string, repo string, opt *ListOptions) ([]*Branch, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview)
+
+	var branches []*Branch
+	resp, err := s.client.Do(ctx, req, &branches)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return branches, resp, nil
+}
+
+// GetBranch gets the specified branch for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#get-branch
+func (s *RepositoriesService) GetBranch(ctx context.Context, owner, repo, branch string) (*Branch, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v", owner, repo, branch)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview)
+
+	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://developer.github.com/v3/repos/branches/#get-branch-protection
+func (s *RepositoriesService) GetBranchProtection(ctx context.Context, owner, repo, branch string) (*Protection, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection", owner, repo, branch)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview)
+
+	p := new(Protection)
+	resp, err := s.client.Do(ctx, req, p)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return p, resp, nil
+}
+
+// GetRequiredStatusChecks gets the required status checks for a given protected branch.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-required-status-checks-of-protected-branch
+func (s *RepositoriesService) GetRequiredStatusChecks(ctx context.Context, owner, repo, branch string) (*RequiredStatusChecks, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_status_checks", owner, repo, branch)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview)
+
+	p := new(RequiredStatusChecks)
+	resp, err := s.client.Do(ctx, req, p)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return p, resp, nil
+}
+
+// ListRequiredStatusChecksContexts lists the required status checks contexts for a given protected branch.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#list-required-status-checks-contexts-of-protected-branch
+func (s *RepositoriesService) ListRequiredStatusChecksContexts(ctx context.Context, owner, repo, branch string) (contexts []string, resp *Response, err error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_status_checks/contexts", owner, repo, branch)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview)
+
+	resp, err = s.client.Do(ctx, req, &contexts)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return contexts, resp, nil
+}
+
+// UpdateBranchProtection updates the protection of a given branch.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#update-branch-protection
+func (s *RepositoriesService) UpdateBranchProtection(ctx context.Context, owner, repo, branch string, preq *ProtectionRequest) (*Protection, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection", owner, repo, branch)
+	req, err := s.client.NewRequest("PUT", u, preq)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview)
+
+	p := new(Protection)
+	resp, err := s.client.Do(ctx, req, p)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return p, resp, nil
+}
+
+// RemoveBranchProtection removes the protection of a given branch.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#remove-branch-protection
+func (s *RepositoriesService) RemoveBranchProtection(ctx context.Context, owner, repo, branch string) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection", owner, repo, branch)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// GetSignaturesProtectedBranch gets required signatures of protected branch.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-required-signatures-of-protected-branch
+func (s *RepositoriesService) GetSignaturesProtectedBranch(ctx context.Context, owner, repo, branch string) (*SignaturesProtectedBranch, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_signatures", owner, repo, branch)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeSignaturePreview)
+
+	p := new(SignaturesProtectedBranch)
+	resp, err := s.client.Do(ctx, req, p)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return p, resp, nil
+}
+
+// RequireSignaturesOnProtectedBranch makes signed commits required on a protected branch.
+// It requires admin access and branch protection to be enabled.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#add-required-signatures-of-protected-branch
+func (s *RepositoriesService) RequireSignaturesOnProtectedBranch(ctx context.Context, owner, repo, branch string) (*SignaturesProtectedBranch, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_signatures", owner, repo, branch)
+	req, err := s.client.NewRequest("POST", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeSignaturePreview)
+
+	r := new(SignaturesProtectedBranch)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, err
+}
+
+// OptionalSignaturesOnProtectedBranch removes required signed commits on a given branch.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#remove-required-signatures-of-protected-branch
+func (s *RepositoriesService) OptionalSignaturesOnProtectedBranch(ctx context.Context, owner, repo, branch string) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_signatures", owner, repo, branch)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeSignaturePreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// UpdateRequiredStatusChecks updates the required status checks for a given protected branch.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#update-required-status-checks-of-protected-branch
+func (s *RepositoriesService) UpdateRequiredStatusChecks(ctx context.Context, owner, repo, branch string, sreq *RequiredStatusChecksRequest) (*RequiredStatusChecks, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_status_checks", owner, repo, branch)
+	req, err := s.client.NewRequest("PATCH", u, sreq)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	sc := new(RequiredStatusChecks)
+	resp, err := s.client.Do(ctx, req, sc)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return sc, resp, nil
+}
+
+// License gets the contents of a repository's license if one is detected.
+//
+// GitHub API docs: https://developer.github.com/v3/licenses/#get-the-contents-of-a-repositorys-license
+func (s *RepositoriesService) License(ctx context.Context, owner, repo string) (*RepositoryLicense, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/license", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	r := &RepositoryLicense{}
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
+
+// GetPullRequestReviewEnforcement gets pull request review enforcement of a protected branch.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-pull-request-review-enforcement-of-protected-branch
+func (s *RepositoriesService) GetPullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string) (*PullRequestReviewsEnforcement, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview)
+
+	r := new(PullRequestReviewsEnforcement)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
+
+// UpdatePullRequestReviewEnforcement patches pull request review enforcement of a protected branch.
+// It requires admin access and branch protection to be enabled.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#update-pull-request-review-enforcement-of-protected-branch
+func (s *RepositoriesService) UpdatePullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string, patch *PullRequestReviewsEnforcementUpdate) (*PullRequestReviewsEnforcement, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch)
+	req, err := s.client.NewRequest("PATCH", u, patch)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview)
+
+	r := new(PullRequestReviewsEnforcement)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, err
+}
+
+// DisableDismissalRestrictions disables dismissal restrictions of a protected branch.
+// It requires admin access and branch protection to be enabled.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#update-pull-request-review-enforcement-of-protected-branch
+func (s *RepositoriesService) DisableDismissalRestrictions(ctx context.Context, owner, repo, branch string) (*PullRequestReviewsEnforcement, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch)
+
+	data := struct {
+		R []interface{} `json:"dismissal_restrictions"`
+	}{[]interface{}{}}
+
+	req, err := s.client.NewRequest("PATCH", u, data)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview)
+
+	r := new(PullRequestReviewsEnforcement)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, err
+}
+
+// RemovePullRequestReviewEnforcement removes pull request enforcement of a protected branch.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#remove-pull-request-review-enforcement-of-protected-branch
+func (s *RepositoriesService) RemovePullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// GetAdminEnforcement gets admin enforcement information of a protected branch.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-admin-enforcement-of-protected-branch
+func (s *RepositoriesService) GetAdminEnforcement(ctx context.Context, owner, repo, branch string) (*AdminEnforcement, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview)
+
+	r := new(AdminEnforcement)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
+
+// AddAdminEnforcement adds admin enforcement to a protected branch.
+// It requires admin access and branch protection to be enabled.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#add-admin-enforcement-of-protected-branch
+func (s *RepositoriesService) AddAdminEnforcement(ctx context.Context, owner, repo, branch string) (*AdminEnforcement, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch)
+	req, err := s.client.NewRequest("POST", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview)
+
+	r := new(AdminEnforcement)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, err
+}
+
+// RemoveAdminEnforcement removes admin enforcement from a protected branch.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#remove-admin-enforcement-of-protected-branch
+func (s *RepositoriesService) RemoveAdminEnforcement(ctx context.Context, owner, repo, branch string) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// repositoryTopics represents a collection of repository topics.
+type repositoryTopics struct {
+	Names []string `json:"names"`
+}
+
+// ListAllTopics lists topics for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#list-all-topics-for-a-repository
+func (s *RepositoriesService) ListAllTopics(ctx context.Context, owner, repo string) ([]string, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/topics", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeTopicsPreview)
+
+	topics := new(repositoryTopics)
+	resp, err := s.client.Do(ctx, req, topics)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return topics.Names, resp, nil
+}
+
+// ReplaceAllTopics replaces topics for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#replace-all-topics-for-a-repository
+func (s *RepositoriesService) ReplaceAllTopics(ctx context.Context, owner, repo string, topics []string) ([]string, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/topics", owner, repo)
+	t := &repositoryTopics{
+		Names: topics,
+	}
+	if t.Names == nil {
+		t.Names = []string{}
+	}
+	req, err := s.client.NewRequest("PUT", u, t)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeTopicsPreview)
+
+	t = new(repositoryTopics)
+	resp, err := s.client.Do(ctx, req, t)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return t.Names, resp, nil
+}
+
+// TransferRequest represents a request to transfer a repository.
+type TransferRequest struct {
+	NewOwner string  `json:"new_owner"`
+	TeamID   []int64 `json:"team_ids,omitempty"`
+}
+
+// Transfer transfers a repository from one account or organization to another.
+//
+// This method might return an *AcceptedError and a status code of
+// 202. This is because this is the status that GitHub returns to signify that
+// it has now scheduled the transfer of the repository in a background task.
+// A follow up request, after a delay of a second or so, should result
+// in a successful request.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#transfer-a-repository
+func (s *RepositoriesService) Transfer(ctx context.Context, owner, repo string, transfer TransferRequest) (*Repository, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/transfer", owner, repo)
+
+	req, err := s.client.NewRequest("POST", u, &transfer)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeRepositoryTransferPreview)
+
+	r := new(Repository)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/repos_collaborators.go b/vendor/github.com/google/go-github/v24/github/repos_collaborators.go
new file mode 100644
index 000000000..757e9f39e
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/repos_collaborators.go
@@ -0,0 +1,137 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// ListCollaboratorsOptions specifies the optional parameters to the
+// RepositoriesService.ListCollaborators method.
+type ListCollaboratorsOptions struct {
+	// Affiliation specifies how collaborators should be filtered by their affiliation.
+	// Possible values are:
+	//     outside - All outside collaborators of an organization-owned repository
+	//     direct - All collaborators with permissions to an organization-owned repository,
+	//              regardless of organization membership status
+	//     all - All collaborators the authenticated user can see
+	//
+	// Default value is "all".
+	Affiliation string `url:"affiliation,omitempty"`
+
+	ListOptions
+}
+
+// ListCollaborators lists the GitHub users that have access to the repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#list-collaborators
+func (s *RepositoriesService) ListCollaborators(ctx context.Context, owner, repo string, opt *ListCollaboratorsOptions) ([]*User, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/collaborators", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
+	var users []*User
+	resp, err := s.client.Do(ctx, req, &users)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return users, resp, nil
+}
+
+// IsCollaborator checks whether the specified GitHub user has collaborator
+// access to the given repo.
+// Note: This will return false if the user is not a collaborator OR the user
+// is not a GitHub user.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#get
+func (s *RepositoriesService) IsCollaborator(ctx context.Context, owner, repo, user string) (bool, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return false, nil, err
+	}
+
+	resp, err := s.client.Do(ctx, req, nil)
+	isCollab, err := parseBoolResponse(err)
+	return isCollab, resp, err
+}
+
+// RepositoryPermissionLevel represents the permission level an organization
+// member has for a given repository.
+type RepositoryPermissionLevel struct {
+	// Possible values: "admin", "write", "read", "none"
+	Permission *string `json:"permission,omitempty"`
+
+	User *User `json:"user,omitempty"`
+}
+
+// GetPermissionLevel retrieves the specific permission level a collaborator has for a given repository.
+// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#review-a-users-permission-level
+func (s *RepositoriesService) GetPermissionLevel(ctx context.Context, owner, repo, user string) (*RepositoryPermissionLevel, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/collaborators/%v/permission", owner, repo, user)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	rpl := new(RepositoryPermissionLevel)
+	resp, err := s.client.Do(ctx, req, rpl)
+	if err != nil {
+		return nil, resp, err
+	}
+	return rpl, resp, nil
+}
+
+// RepositoryAddCollaboratorOptions specifies the optional parameters to the
+// RepositoriesService.AddCollaborator method.
+type RepositoryAddCollaboratorOptions struct {
+	// Permission specifies the permission to grant the user on this repository.
+	// Possible values are:
+	//     pull - team members can pull, but not push to or administer this repository
+	//     push - team members can pull and push, but not administer this repository
+	//     admin - team members can pull, push and administer this repository
+	//
+	// Default value is "push". This option is only valid for organization-owned repositories.
+	Permission string `json:"permission,omitempty"`
+}
+
+// AddCollaborator sends an invitation to the specified GitHub user
+// to become a collaborator to the given repo.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#add-user-as-a-collaborator
+func (s *RepositoriesService) AddCollaborator(ctx context.Context, owner, repo, user string, opt *RepositoryAddCollaboratorOptions) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user)
+	req, err := s.client.NewRequest("PUT", u, opt)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// RemoveCollaborator removes the specified GitHub user as collaborator from the given repo.
+// Note: Does not return error if a valid user that is not a collaborator is removed.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#remove-collaborator
+func (s *RepositoriesService) RemoveCollaborator(ctx context.Context, owner, repo, user string) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/repos_comments.go b/vendor/github.com/google/go-github/v24/github/repos_comments.go
new file mode 100644
index 000000000..fa2377d40
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/repos_comments.go
@@ -0,0 +1,161 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// RepositoryComment represents a comment for a commit, file, or line in a repository.
+type RepositoryComment struct {
+	HTMLURL   *string    `json:"html_url,omitempty"`
+	URL       *string    `json:"url,omitempty"`
+	ID        *int64     `json:"id,omitempty"`
+	CommitID  *string    `json:"commit_id,omitempty"`
+	User      *User      `json:"user,omitempty"`
+	Reactions *Reactions `json:"reactions,omitempty"`
+	CreatedAt *time.Time `json:"created_at,omitempty"`
+	UpdatedAt *time.Time `json:"updated_at,omitempty"`
+
+	// User-mutable fields
+	Body *string `json:"body"`
+	// User-initialized fields
+	Path     *string `json:"path,omitempty"`
+	Position *int    `json:"position,omitempty"`
+}
+
+func (r RepositoryComment) String() string {
+	return Stringify(r)
+}
+
+// ListComments lists all the comments for the repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/comments/#list-commit-comments-for-a-repository
+func (s *RepositoriesService) ListComments(ctx context.Context, owner, repo string, opt *ListOptions) ([]*RepositoryComment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/comments", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	var comments []*RepositoryComment
+	resp, err := s.client.Do(ctx, req, &comments)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return comments, resp, nil
+}
+
+// ListCommitComments lists all the comments for a given commit SHA.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/comments/#list-comments-for-a-single-commit
+func (s *RepositoriesService) ListCommitComments(ctx context.Context, owner, repo, sha string, opt *ListOptions) ([]*RepositoryComment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/commits/%v/comments", owner, repo, sha)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	var comments []*RepositoryComment
+	resp, err := s.client.Do(ctx, req, &comments)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return comments, resp, nil
+}
+
+// CreateComment creates a comment for the given commit.
+// Note: GitHub allows for comments to be created for non-existing files and positions.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/comments/#create-a-commit-comment
+func (s *RepositoriesService) CreateComment(ctx context.Context, owner, repo, sha string, comment *RepositoryComment) (*RepositoryComment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/commits/%v/comments", owner, repo, sha)
+	req, err := s.client.NewRequest("POST", u, comment)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	c := new(RepositoryComment)
+	resp, err := s.client.Do(ctx, req, c)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return c, resp, nil
+}
+
+// GetComment gets a single comment from a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/comments/#get-a-single-commit-comment
+func (s *RepositoriesService) GetComment(ctx context.Context, owner, repo string, id int64) (*RepositoryComment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/comments/%v", owner, repo, id)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	c := new(RepositoryComment)
+	resp, err := s.client.Do(ctx, req, c)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return c, resp, nil
+}
+
+// UpdateComment updates the body of a single comment.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/comments/#update-a-commit-comment
+func (s *RepositoriesService) UpdateComment(ctx context.Context, owner, repo string, id int64, comment *RepositoryComment) (*RepositoryComment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/comments/%v", owner, repo, id)
+	req, err := s.client.NewRequest("PATCH", u, comment)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	c := new(RepositoryComment)
+	resp, err := s.client.Do(ctx, req, c)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return c, resp, nil
+}
+
+// DeleteComment deletes a single comment from a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/comments/#delete-a-commit-comment
+func (s *RepositoriesService) DeleteComment(ctx context.Context, owner, repo string, id int64) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/comments/%v", owner, repo, id)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/repos_commits.go b/vendor/github.com/google/go-github/v24/github/repos_commits.go
new file mode 100644
index 000000000..a4c621596
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/repos_commits.go
@@ -0,0 +1,233 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"net/url"
+	"time"
+)
+
+// RepositoryCommit represents a commit in a repo.
+// Note that it's wrapping a Commit, so author/committer information is in two places,
+// but contain different details about them: in RepositoryCommit "github details", in Commit - "git details".
+type RepositoryCommit struct {
+	SHA         *string  `json:"sha,omitempty"`
+	Commit      *Commit  `json:"commit,omitempty"`
+	Author      *User    `json:"author,omitempty"`
+	Committer   *User    `json:"committer,omitempty"`
+	Parents     []Commit `json:"parents,omitempty"`
+	HTMLURL     *string  `json:"html_url,omitempty"`
+	URL         *string  `json:"url,omitempty"`
+	CommentsURL *string  `json:"comments_url,omitempty"`
+
+	// Details about how many changes were made in this commit. Only filled in during GetCommit!
+	Stats *CommitStats `json:"stats,omitempty"`
+	// Details about which files, and how this commit touched. Only filled in during GetCommit!
+	Files []CommitFile `json:"files,omitempty"`
+}
+
+func (r RepositoryCommit) String() string {
+	return Stringify(r)
+}
+
+// CommitStats represents the number of additions / deletions from a file in a given RepositoryCommit or GistCommit.
+type CommitStats struct {
+	Additions *int `json:"additions,omitempty"`
+	Deletions *int `json:"deletions,omitempty"`
+	Total     *int `json:"total,omitempty"`
+}
+
+func (c CommitStats) String() string {
+	return Stringify(c)
+}
+
+// CommitFile represents a file modified in a commit.
+type CommitFile struct {
+	SHA              *string `json:"sha,omitempty"`
+	Filename         *string `json:"filename,omitempty"`
+	Additions        *int    `json:"additions,omitempty"`
+	Deletions        *int    `json:"deletions,omitempty"`
+	Changes          *int    `json:"changes,omitempty"`
+	Status           *string `json:"status,omitempty"`
+	Patch            *string `json:"patch,omitempty"`
+	BlobURL          *string `json:"blob_url,omitempty"`
+	RawURL           *string `json:"raw_url,omitempty"`
+	ContentsURL      *string `json:"contents_url,omitempty"`
+	PreviousFilename *string `json:"previous_filename,omitempty"`
+}
+
+func (c CommitFile) String() string {
+	return Stringify(c)
+}
+
+// CommitsComparison is the result of comparing two commits.
+// See CompareCommits() for details.
+type CommitsComparison struct {
+	BaseCommit      *RepositoryCommit `json:"base_commit,omitempty"`
+	MergeBaseCommit *RepositoryCommit `json:"merge_base_commit,omitempty"`
+
+	// Head can be 'behind' or 'ahead'
+	Status       *string `json:"status,omitempty"`
+	AheadBy      *int    `json:"ahead_by,omitempty"`
+	BehindBy     *int    `json:"behind_by,omitempty"`
+	TotalCommits *int    `json:"total_commits,omitempty"`
+
+	Commits []RepositoryCommit `json:"commits,omitempty"`
+
+	Files []CommitFile `json:"files,omitempty"`
+
+	HTMLURL      *string `json:"html_url,omitempty"`
+	PermalinkURL *string `json:"permalink_url,omitempty"`
+	DiffURL      *string `json:"diff_url,omitempty"`
+	PatchURL     *string `json:"patch_url,omitempty"`
+	URL          *string `json:"url,omitempty"` // API URL.
+}
+
+func (c CommitsComparison) String() string {
+	return Stringify(c)
+}
+
+// CommitsListOptions specifies the optional parameters to the
+// RepositoriesService.ListCommits method.
+type CommitsListOptions struct {
+	// SHA or branch to start listing Commits from.
+	SHA string `url:"sha,omitempty"`
+
+	// Path that should be touched by the returned Commits.
+	Path string `url:"path,omitempty"`
+
+	// Author of by which to filter Commits.
+	Author string `url:"author,omitempty"`
+
+	// Since when should Commits be included in the response.
+	Since time.Time `url:"since,omitempty"`
+
+	// Until when should Commits be included in the response.
+	Until time.Time `url:"until,omitempty"`
+
+	ListOptions
+}
+
+// ListCommits lists the commits of a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/commits/#list
+func (s *RepositoriesService) ListCommits(ctx context.Context, owner, repo string, opt *CommitsListOptions) ([]*RepositoryCommit, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/commits", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var commits []*RepositoryCommit
+	resp, err := s.client.Do(ctx, req, &commits)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return commits, resp, nil
+}
+
+// GetCommit fetches the specified commit, including all details about it.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/commits/#get-a-single-commit
+// See also: https://developer.github.com/v3/git/commits/#get-a-single-commit provides the same functionality
+func (s *RepositoriesService) GetCommit(ctx context.Context, owner, repo, sha string) (*RepositoryCommit, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/commits/%v", owner, repo, sha)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	commit := new(RepositoryCommit)
+	resp, err := s.client.Do(ctx, req, commit)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return commit, resp, nil
+}
+
+// GetCommitRaw fetches the specified commit in raw (diff or patch) format.
+func (s *RepositoriesService) GetCommitRaw(ctx context.Context, owner string, repo string, sha string, opt RawOptions) (string, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/commits/%v", owner, repo, sha)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return "", nil, err
+	}
+
+	switch opt.Type {
+	case Diff:
+		req.Header.Set("Accept", mediaTypeV3Diff)
+	case Patch:
+		req.Header.Set("Accept", mediaTypeV3Patch)
+	default:
+		return "", nil, fmt.Errorf("unsupported raw type %d", opt.Type)
+	}
+
+	var buf bytes.Buffer
+	resp, err := s.client.Do(ctx, req, &buf)
+	if err != nil {
+		return "", resp, err
+	}
+
+	return buf.String(), resp, nil
+}
+
+// GetCommitSHA1 gets the SHA-1 of a commit reference. If a last-known SHA1 is
+// supplied and no new commits have occurred, a 304 Unmodified response is returned.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/commits/#get-the-sha-1-of-a-commit-reference
+func (s *RepositoriesService) GetCommitSHA1(ctx context.Context, owner, repo, ref, lastSHA string) (string, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/commits/%v", owner, repo, url.QueryEscape(ref))
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return "", nil, err
+	}
+	if lastSHA != "" {
+		req.Header.Set("If-None-Match", `"`+lastSHA+`"`)
+	}
+
+	req.Header.Set("Accept", mediaTypeV3SHA)
+
+	var buf bytes.Buffer
+	resp, err := s.client.Do(ctx, req, &buf)
+	if err != nil {
+		return "", resp, err
+	}
+
+	return buf.String(), resp, nil
+}
+
+// CompareCommits compares a range of commits with each other.
+// todo: support media formats - https://github.com/google/go-github/issues/6
+//
+// GitHub API docs: https://developer.github.com/v3/repos/commits/#compare-two-commits
+func (s *RepositoriesService) CompareCommits(ctx context.Context, owner, repo string, base, head string) (*CommitsComparison, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/compare/%v...%v", owner, repo, base, head)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	comp := new(CommitsComparison)
+	resp, err := s.client.Do(ctx, req, comp)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return comp, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/repos_community_health.go b/vendor/github.com/google/go-github/v24/github/repos_community_health.go
new file mode 100644
index 000000000..73d1d573b
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/repos_community_health.go
@@ -0,0 +1,59 @@
+// Copyright 2017 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// Metric represents the different fields for one file in community health files.
+type Metric struct {
+	Name    *string `json:"name"`
+	Key     *string `json:"key"`
+	URL     *string `json:"url"`
+	HTMLURL *string `json:"html_url"`
+}
+
+// CommunityHealthFiles represents the different files in the community health metrics response.
+type CommunityHealthFiles struct {
+	CodeOfConduct       *Metric `json:"code_of_conduct"`
+	Contributing        *Metric `json:"contributing"`
+	IssueTemplate       *Metric `json:"issue_template"`
+	PullRequestTemplate *Metric `json:"pull_request_template"`
+	License             *Metric `json:"license"`
+	Readme              *Metric `json:"readme"`
+}
+
+// CommunityHealthMetrics represents a response containing the community metrics of a repository.
+type CommunityHealthMetrics struct {
+	HealthPercentage *int                  `json:"health_percentage"`
+	Files            *CommunityHealthFiles `json:"files"`
+	UpdatedAt        *time.Time            `json:"updated_at"`
+}
+
+// GetCommunityHealthMetrics retrieves all the community health  metrics for a  repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/community/#retrieve-community-health-metrics
+func (s *RepositoriesService) GetCommunityHealthMetrics(ctx context.Context, owner, repo string) (*CommunityHealthMetrics, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/community/profile", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeRepositoryCommunityHealthMetricsPreview)
+
+	metrics := &CommunityHealthMetrics{}
+	resp, err := s.client.Do(ctx, req, metrics)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return metrics, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/repos_contents.go b/vendor/github.com/google/go-github/v24/github/repos_contents.go
new file mode 100644
index 000000000..bf6cabc5c
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/repos_contents.go
@@ -0,0 +1,269 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Repository contents API methods.
+// GitHub API docs: https://developer.github.com/v3/repos/contents/
+
+package github
+
+import (
+	"context"
+	"encoding/base64"
+	"encoding/json"
+	"fmt"
+	"io"
+	"net/http"
+	"net/url"
+	"path"
+)
+
+// RepositoryContent represents a file or directory in a github repository.
+type RepositoryContent struct {
+	Type *string `json:"type,omitempty"`
+	// Target is only set if the type is "symlink" and the target is not a normal file.
+	// If Target is set, Path will be the symlink path.
+	Target   *string `json:"target,omitempty"`
+	Encoding *string `json:"encoding,omitempty"`
+	Size     *int    `json:"size,omitempty"`
+	Name     *string `json:"name,omitempty"`
+	Path     *string `json:"path,omitempty"`
+	// Content contains the actual file content, which may be encoded.
+	// Callers should call GetContent which will decode the content if
+	// necessary.
+	Content     *string `json:"content,omitempty"`
+	SHA         *string `json:"sha,omitempty"`
+	URL         *string `json:"url,omitempty"`
+	GitURL      *string `json:"git_url,omitempty"`
+	HTMLURL     *string `json:"html_url,omitempty"`
+	DownloadURL *string `json:"download_url,omitempty"`
+}
+
+// RepositoryContentResponse holds the parsed response from CreateFile, UpdateFile, and DeleteFile.
+type RepositoryContentResponse struct {
+	Content *RepositoryContent `json:"content,omitempty"`
+	Commit  `json:"commit,omitempty"`
+}
+
+// RepositoryContentFileOptions specifies optional parameters for CreateFile, UpdateFile, and DeleteFile.
+type RepositoryContentFileOptions struct {
+	Message   *string       `json:"message,omitempty"`
+	Content   []byte        `json:"content,omitempty"` // unencoded
+	SHA       *string       `json:"sha,omitempty"`
+	Branch    *string       `json:"branch,omitempty"`
+	Author    *CommitAuthor `json:"author,omitempty"`
+	Committer *CommitAuthor `json:"committer,omitempty"`
+}
+
+// RepositoryContentGetOptions represents an optional ref parameter, which can be a SHA,
+// branch, or tag
+type RepositoryContentGetOptions struct {
+	Ref string `url:"ref,omitempty"`
+}
+
+// String converts RepositoryContent to a string. It's primarily for testing.
+func (r RepositoryContent) String() string {
+	return Stringify(r)
+}
+
+// GetContent returns the content of r, decoding it if necessary.
+func (r *RepositoryContent) GetContent() (string, error) {
+	var encoding string
+	if r.Encoding != nil {
+		encoding = *r.Encoding
+	}
+
+	switch encoding {
+	case "base64":
+		c, err := base64.StdEncoding.DecodeString(*r.Content)
+		return string(c), err
+	case "":
+		if r.Content == nil {
+			return "", nil
+		}
+		return *r.Content, nil
+	default:
+		return "", fmt.Errorf("unsupported content encoding: %v", encoding)
+	}
+}
+
+// GetReadme gets the Readme file for the repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/contents/#get-the-readme
+func (s *RepositoriesService) GetReadme(ctx context.Context, owner, repo string, opt *RepositoryContentGetOptions) (*RepositoryContent, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/readme", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+	readme := new(RepositoryContent)
+	resp, err := s.client.Do(ctx, req, readme)
+	if err != nil {
+		return nil, resp, err
+	}
+	return readme, resp, nil
+}
+
+// DownloadContents returns an io.ReadCloser that reads the contents of the
+// specified file. This function will work with files of any size, as opposed
+// to GetContents which is limited to 1 Mb files. It is the caller's
+// responsibility to close the ReadCloser.
+func (s *RepositoriesService) DownloadContents(ctx context.Context, owner, repo, filepath string, opt *RepositoryContentGetOptions) (io.ReadCloser, error) {
+	dir := path.Dir(filepath)
+	filename := path.Base(filepath)
+	_, dirContents, _, err := s.GetContents(ctx, owner, repo, dir, opt)
+	if err != nil {
+		return nil, err
+	}
+	for _, contents := range dirContents {
+		if *contents.Name == filename {
+			if contents.DownloadURL == nil || *contents.DownloadURL == "" {
+				return nil, fmt.Errorf("No download link found for %s", filepath)
+			}
+			resp, err := s.client.client.Get(*contents.DownloadURL)
+			if err != nil {
+				return nil, err
+			}
+			return resp.Body, nil
+		}
+	}
+	return nil, fmt.Errorf("No file named %s found in %s", filename, dir)
+}
+
+// GetContents can return either the metadata and content of a single file
+// (when path references a file) or the metadata of all the files and/or
+// subdirectories of a directory (when path references a directory). To make it
+// easy to distinguish between both result types and to mimic the API as much
+// as possible, both result types will be returned but only one will contain a
+// value and the other will be nil.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/contents/#get-contents
+func (s *RepositoriesService) GetContents(ctx context.Context, owner, repo, path string, opt *RepositoryContentGetOptions) (fileContent *RepositoryContent, directoryContent []*RepositoryContent, resp *Response, err error) {
+	escapedPath := (&url.URL{Path: path}).String()
+	u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, escapedPath)
+	u, err = addOptions(u, opt)
+	if err != nil {
+		return nil, nil, nil, err
+	}
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, nil, err
+	}
+	var rawJSON json.RawMessage
+	resp, err = s.client.Do(ctx, req, &rawJSON)
+	if err != nil {
+		return nil, nil, resp, err
+	}
+	fileUnmarshalError := json.Unmarshal(rawJSON, &fileContent)
+	if fileUnmarshalError == nil {
+		return fileContent, nil, resp, nil
+	}
+	directoryUnmarshalError := json.Unmarshal(rawJSON, &directoryContent)
+	if directoryUnmarshalError == nil {
+		return nil, directoryContent, resp, nil
+	}
+	return nil, nil, resp, fmt.Errorf("unmarshalling failed for both file and directory content: %s and %s", fileUnmarshalError, directoryUnmarshalError)
+}
+
+// CreateFile creates a new file in a repository at the given path and returns
+// the commit and file metadata.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/contents/#create-a-file
+func (s *RepositoriesService) CreateFile(ctx context.Context, owner, repo, path string, opt *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path)
+	req, err := s.client.NewRequest("PUT", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+	createResponse := new(RepositoryContentResponse)
+	resp, err := s.client.Do(ctx, req, createResponse)
+	if err != nil {
+		return nil, resp, err
+	}
+	return createResponse, resp, nil
+}
+
+// UpdateFile updates a file in a repository at the given path and returns the
+// commit and file metadata. Requires the blob SHA of the file being updated.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/contents/#update-a-file
+func (s *RepositoriesService) UpdateFile(ctx context.Context, owner, repo, path string, opt *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path)
+	req, err := s.client.NewRequest("PUT", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+	updateResponse := new(RepositoryContentResponse)
+	resp, err := s.client.Do(ctx, req, updateResponse)
+	if err != nil {
+		return nil, resp, err
+	}
+	return updateResponse, resp, nil
+}
+
+// DeleteFile deletes a file from a repository and returns the commit.
+// Requires the blob SHA of the file to be deleted.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/contents/#delete-a-file
+func (s *RepositoriesService) DeleteFile(ctx context.Context, owner, repo, path string, opt *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path)
+	req, err := s.client.NewRequest("DELETE", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+	deleteResponse := new(RepositoryContentResponse)
+	resp, err := s.client.Do(ctx, req, deleteResponse)
+	if err != nil {
+		return nil, resp, err
+	}
+	return deleteResponse, resp, nil
+}
+
+// archiveFormat is used to define the archive type when calling GetArchiveLink.
+type archiveFormat string
+
+const (
+	// Tarball specifies an archive in gzipped tar format.
+	Tarball archiveFormat = "tarball"
+
+	// Zipball specifies an archive in zip format.
+	Zipball archiveFormat = "zipball"
+)
+
+// GetArchiveLink returns an URL to download a tarball or zipball archive for a
+// repository. The archiveFormat can be specified by either the github.Tarball
+// or github.Zipball constant.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/contents/#get-archive-link
+func (s *RepositoriesService) GetArchiveLink(ctx context.Context, owner, repo string, archiveformat archiveFormat, opt *RepositoryContentGetOptions) (*url.URL, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/%s", owner, repo, archiveformat)
+	if opt != nil && opt.Ref != "" {
+		u += fmt.Sprintf("/%s", opt.Ref)
+	}
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+	var resp *http.Response
+	// Use http.DefaultTransport if no custom Transport is configured
+	req = withContext(ctx, req)
+	if s.client.client.Transport == nil {
+		resp, err = http.DefaultTransport.RoundTrip(req)
+	} else {
+		resp, err = s.client.client.Transport.RoundTrip(req)
+	}
+	if err != nil {
+		return nil, nil, err
+	}
+	resp.Body.Close()
+	if resp.StatusCode != http.StatusFound {
+		return nil, newResponse(resp), fmt.Errorf("unexpected status code: %s", resp.Status)
+	}
+	parsedURL, err := url.Parse(resp.Header.Get("Location"))
+	return parsedURL, newResponse(resp), err
+}
diff --git a/vendor/github.com/google/go-github/v24/github/repos_deployments.go b/vendor/github.com/google/go-github/v24/github/repos_deployments.go
new file mode 100644
index 000000000..604632e91
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/repos_deployments.go
@@ -0,0 +1,229 @@
+// Copyright 2014 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"strings"
+)
+
+// Deployment represents a deployment in a repo
+type Deployment struct {
+	URL           *string         `json:"url,omitempty"`
+	ID            *int64          `json:"id,omitempty"`
+	SHA           *string         `json:"sha,omitempty"`
+	Ref           *string         `json:"ref,omitempty"`
+	Task          *string         `json:"task,omitempty"`
+	Payload       json.RawMessage `json:"payload,omitempty"`
+	Environment   *string         `json:"environment,omitempty"`
+	Description   *string         `json:"description,omitempty"`
+	Creator       *User           `json:"creator,omitempty"`
+	CreatedAt     *Timestamp      `json:"created_at,omitempty"`
+	UpdatedAt     *Timestamp      `json:"updated_at,omitempty"`
+	StatusesURL   *string         `json:"statuses_url,omitempty"`
+	RepositoryURL *string         `json:"repository_url,omitempty"`
+	NodeID        *string         `json:"node_id,omitempty"`
+}
+
+// DeploymentRequest represents a deployment request
+type DeploymentRequest struct {
+	Ref                   *string   `json:"ref,omitempty"`
+	Task                  *string   `json:"task,omitempty"`
+	AutoMerge             *bool     `json:"auto_merge,omitempty"`
+	RequiredContexts      *[]string `json:"required_contexts,omitempty"`
+	Payload               *string   `json:"payload,omitempty"`
+	Environment           *string   `json:"environment,omitempty"`
+	Description           *string   `json:"description,omitempty"`
+	TransientEnvironment  *bool     `json:"transient_environment,omitempty"`
+	ProductionEnvironment *bool     `json:"production_environment,omitempty"`
+}
+
+// DeploymentsListOptions specifies the optional parameters to the
+// RepositoriesService.ListDeployments method.
+type DeploymentsListOptions struct {
+	// SHA of the Deployment.
+	SHA string `url:"sha,omitempty"`
+
+	// List deployments for a given ref.
+	Ref string `url:"ref,omitempty"`
+
+	// List deployments for a given task.
+	Task string `url:"task,omitempty"`
+
+	// List deployments for a given environment.
+	Environment string `url:"environment,omitempty"`
+
+	ListOptions
+}
+
+// ListDeployments lists the deployments of a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/deployments/#list-deployments
+func (s *RepositoriesService) ListDeployments(ctx context.Context, owner, repo string, opt *DeploymentsListOptions) ([]*Deployment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/deployments", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var deployments []*Deployment
+	resp, err := s.client.Do(ctx, req, &deployments)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return deployments, resp, nil
+}
+
+// GetDeployment returns a single deployment of a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/deployments/#get-a-single-deployment
+func (s *RepositoriesService) GetDeployment(ctx context.Context, owner, repo string, deploymentID int64) (*Deployment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/deployments/%v", owner, repo, deploymentID)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	deployment := new(Deployment)
+	resp, err := s.client.Do(ctx, req, deployment)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return deployment, resp, nil
+}
+
+// CreateDeployment creates a new deployment for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/deployments/#create-a-deployment
+func (s *RepositoriesService) CreateDeployment(ctx context.Context, owner, repo string, request *DeploymentRequest) (*Deployment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/deployments", owner, repo)
+
+	req, err := s.client.NewRequest("POST", u, request)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeDeploymentStatusPreview, mediaTypeExpandDeploymentStatusPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	d := new(Deployment)
+	resp, err := s.client.Do(ctx, req, d)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return d, resp, nil
+}
+
+// DeploymentStatus represents the status of a
+// particular deployment.
+type DeploymentStatus struct {
+	ID *int64 `json:"id,omitempty"`
+	// State is the deployment state.
+	// Possible values are: "pending", "success", "failure", "error", "inactive".
+	State         *string    `json:"state,omitempty"`
+	Creator       *User      `json:"creator,omitempty"`
+	Description   *string    `json:"description,omitempty"`
+	TargetURL     *string    `json:"target_url,omitempty"`
+	CreatedAt     *Timestamp `json:"created_at,omitempty"`
+	UpdatedAt     *Timestamp `json:"updated_at,omitempty"`
+	DeploymentURL *string    `json:"deployment_url,omitempty"`
+	RepositoryURL *string    `json:"repository_url,omitempty"`
+	NodeID        *string    `json:"node_id,omitempty"`
+}
+
+// DeploymentStatusRequest represents a deployment request
+type DeploymentStatusRequest struct {
+	State          *string `json:"state,omitempty"`
+	LogURL         *string `json:"log_url,omitempty"`
+	Description    *string `json:"description,omitempty"`
+	Environment    *string `json:"environment,omitempty"`
+	EnvironmentURL *string `json:"environment_url,omitempty"`
+	AutoInactive   *bool   `json:"auto_inactive,omitempty"`
+}
+
+// ListDeploymentStatuses lists the statuses of a given deployment of a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/deployments/#list-deployment-statuses
+func (s *RepositoriesService) ListDeploymentStatuses(ctx context.Context, owner, repo string, deployment int64, opt *ListOptions) ([]*DeploymentStatus, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/deployments/%v/statuses", owner, repo, deployment)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var statuses []*DeploymentStatus
+	resp, err := s.client.Do(ctx, req, &statuses)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return statuses, resp, nil
+}
+
+// GetDeploymentStatus returns a single deployment status of a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/deployments/#get-a-single-deployment-status
+func (s *RepositoriesService) GetDeploymentStatus(ctx context.Context, owner, repo string, deploymentID, deploymentStatusID int64) (*DeploymentStatus, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/deployments/%v/statuses/%v", owner, repo, deploymentID, deploymentStatusID)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeDeploymentStatusPreview, mediaTypeExpandDeploymentStatusPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	d := new(DeploymentStatus)
+	resp, err := s.client.Do(ctx, req, d)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return d, resp, nil
+}
+
+// CreateDeploymentStatus creates a new status for a deployment.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/deployments/#create-a-deployment-status
+func (s *RepositoriesService) CreateDeploymentStatus(ctx context.Context, owner, repo string, deployment int64, request *DeploymentStatusRequest) (*DeploymentStatus, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/deployments/%v/statuses", owner, repo, deployment)
+
+	req, err := s.client.NewRequest("POST", u, request)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeDeploymentStatusPreview, mediaTypeExpandDeploymentStatusPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	d := new(DeploymentStatus)
+	resp, err := s.client.Do(ctx, req, d)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return d, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/repos_forks.go b/vendor/github.com/google/go-github/v24/github/repos_forks.go
new file mode 100644
index 000000000..bfff27bb9
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/repos_forks.go
@@ -0,0 +1,96 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+
+	"encoding/json"
+)
+
+// RepositoryListForksOptions specifies the optional parameters to the
+// RepositoriesService.ListForks method.
+type RepositoryListForksOptions struct {
+	// How to sort the forks list. Possible values are: newest, oldest,
+	// watchers. Default is "newest".
+	Sort string `url:"sort,omitempty"`
+
+	ListOptions
+}
+
+// ListForks lists the forks of the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/forks/#list-forks
+func (s *RepositoriesService) ListForks(ctx context.Context, owner, repo string, opt *RepositoryListForksOptions) ([]*Repository, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/forks", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when topics API fully launches.
+	req.Header.Set("Accept", mediaTypeTopicsPreview)
+
+	var repos []*Repository
+	resp, err := s.client.Do(ctx, req, &repos)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return repos, resp, nil
+}
+
+// RepositoryCreateForkOptions specifies the optional parameters to the
+// RepositoriesService.CreateFork method.
+type RepositoryCreateForkOptions struct {
+	// The organization to fork the repository into.
+	Organization string `url:"organization,omitempty"`
+}
+
+// CreateFork creates a fork of the specified repository.
+//
+// This method might return an *AcceptedError and a status code of
+// 202. This is because this is the status that GitHub returns to signify that
+// it is now computing creating the fork in a background task. In this event,
+// the Repository value will be returned, which includes the details about the pending fork.
+// A follow up request, after a delay of a second or so, should result
+// in a successful request.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/forks/#create-a-fork
+func (s *RepositoriesService) CreateFork(ctx context.Context, owner, repo string, opt *RepositoryCreateForkOptions) (*Repository, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/forks", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("POST", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	fork := new(Repository)
+	resp, err := s.client.Do(ctx, req, fork)
+	if err != nil {
+		// Persist AcceptedError's metadata to the Repository object.
+		if aerr, ok := err.(*AcceptedError); ok {
+			if err := json.Unmarshal(aerr.Raw, fork); err != nil {
+				return fork, resp, err
+			}
+
+			return fork, resp, err
+		}
+		return nil, resp, err
+	}
+
+	return fork, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/repos_hooks.go b/vendor/github.com/google/go-github/v24/github/repos_hooks.go
new file mode 100644
index 000000000..7674947df
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/repos_hooks.go
@@ -0,0 +1,226 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// WebHookPayload represents the data that is received from GitHub when a push
+// event hook is triggered. The format of these payloads pre-date most of the
+// GitHub v3 API, so there are lots of minor incompatibilities with the types
+// defined in the rest of the API. Therefore, several types are duplicated
+// here to account for these differences.
+//
+// GitHub API docs: https://help.github.com/articles/post-receive-hooks
+type WebHookPayload struct {
+	After      *string         `json:"after,omitempty"`
+	Before     *string         `json:"before,omitempty"`
+	Commits    []WebHookCommit `json:"commits,omitempty"`
+	Compare    *string         `json:"compare,omitempty"`
+	Created    *bool           `json:"created,omitempty"`
+	Deleted    *bool           `json:"deleted,omitempty"`
+	Forced     *bool           `json:"forced,omitempty"`
+	HeadCommit *WebHookCommit  `json:"head_commit,omitempty"`
+	Pusher     *User           `json:"pusher,omitempty"`
+	Ref        *string         `json:"ref,omitempty"`
+	Repo       *Repository     `json:"repository,omitempty"`
+	Sender     *User           `json:"sender,omitempty"`
+}
+
+func (w WebHookPayload) String() string {
+	return Stringify(w)
+}
+
+// WebHookCommit represents the commit variant we receive from GitHub in a
+// WebHookPayload.
+type WebHookCommit struct {
+	Added     []string       `json:"added,omitempty"`
+	Author    *WebHookAuthor `json:"author,omitempty"`
+	Committer *WebHookAuthor `json:"committer,omitempty"`
+	Distinct  *bool          `json:"distinct,omitempty"`
+	ID        *string        `json:"id,omitempty"`
+	Message   *string        `json:"message,omitempty"`
+	Modified  []string       `json:"modified,omitempty"`
+	Removed   []string       `json:"removed,omitempty"`
+	Timestamp *time.Time     `json:"timestamp,omitempty"`
+}
+
+func (w WebHookCommit) String() string {
+	return Stringify(w)
+}
+
+// WebHookAuthor represents the author or committer of a commit, as specified
+// in a WebHookCommit. The commit author may not correspond to a GitHub User.
+type WebHookAuthor struct {
+	Email    *string `json:"email,omitempty"`
+	Name     *string `json:"name,omitempty"`
+	Username *string `json:"username,omitempty"`
+}
+
+func (w WebHookAuthor) String() string {
+	return Stringify(w)
+}
+
+// Hook represents a GitHub (web and service) hook for a repository.
+type Hook struct {
+	CreatedAt *time.Time `json:"created_at,omitempty"`
+	UpdatedAt *time.Time `json:"updated_at,omitempty"`
+	URL       *string    `json:"url,omitempty"`
+	ID        *int64     `json:"id,omitempty"`
+
+	// Only the following fields are used when creating a hook.
+	// Config is required.
+	Config map[string]interface{} `json:"config,omitempty"`
+	Events []string               `json:"events,omitempty"`
+	Active *bool                  `json:"active,omitempty"`
+}
+
+func (h Hook) String() string {
+	return Stringify(h)
+}
+
+// createHookRequest is a subset of Hook and is used internally
+// by CreateHook to pass only the known fields for the endpoint.
+//
+// See https://github.com/google/go-github/issues/1015 for more
+// information.
+type createHookRequest struct {
+	// Config is required.
+	Name   string                 `json:"name"`
+	Config map[string]interface{} `json:"config,omitempty"`
+	Events []string               `json:"events,omitempty"`
+	Active *bool                  `json:"active,omitempty"`
+}
+
+// CreateHook creates a Hook for the specified repository.
+// Config is a required field.
+//
+// Note that only a subset of the hook fields are used and hook must
+// not be nil.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/hooks/#create-a-hook
+func (s *RepositoriesService) CreateHook(ctx context.Context, owner, repo string, hook *Hook) (*Hook, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/hooks", owner, repo)
+
+	hookReq := &createHookRequest{
+		Name:   "web",
+		Events: hook.Events,
+		Active: hook.Active,
+		Config: hook.Config,
+	}
+
+	req, err := s.client.NewRequest("POST", u, hookReq)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	h := new(Hook)
+	resp, err := s.client.Do(ctx, req, h)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return h, resp, nil
+}
+
+// ListHooks lists all Hooks for the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/hooks/#list
+func (s *RepositoriesService) ListHooks(ctx context.Context, owner, repo string, opt *ListOptions) ([]*Hook, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/hooks", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var hooks []*Hook
+	resp, err := s.client.Do(ctx, req, &hooks)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return hooks, resp, nil
+}
+
+// GetHook returns a single specified Hook.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/hooks/#get-single-hook
+func (s *RepositoriesService) GetHook(ctx context.Context, owner, repo string, id int64) (*Hook, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/hooks/%d", owner, repo, id)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+	h := new(Hook)
+	resp, err := s.client.Do(ctx, req, h)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return h, resp, nil
+}
+
+// EditHook updates a specified Hook.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/hooks/#edit-a-hook
+func (s *RepositoriesService) EditHook(ctx context.Context, owner, repo string, id int64, hook *Hook) (*Hook, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/hooks/%d", owner, repo, id)
+	req, err := s.client.NewRequest("PATCH", u, hook)
+	if err != nil {
+		return nil, nil, err
+	}
+	h := new(Hook)
+	resp, err := s.client.Do(ctx, req, h)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return h, resp, nil
+}
+
+// DeleteHook deletes a specified Hook.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/hooks/#delete-a-hook
+func (s *RepositoriesService) DeleteHook(ctx context.Context, owner, repo string, id int64) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/hooks/%d", owner, repo, id)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
+
+// PingHook triggers a 'ping' event to be sent to the Hook.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/hooks/#ping-a-hook
+func (s *RepositoriesService) PingHook(ctx context.Context, owner, repo string, id int64) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/hooks/%d/pings", owner, repo, id)
+	req, err := s.client.NewRequest("POST", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
+
+// TestHook triggers a test Hook by github.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/hooks/#test-a-push-hook
+func (s *RepositoriesService) TestHook(ctx context.Context, owner, repo string, id int64) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/hooks/%d/tests", owner, repo, id)
+	req, err := s.client.NewRequest("POST", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/repos_invitations.go b/vendor/github.com/google/go-github/v24/github/repos_invitations.go
new file mode 100644
index 000000000..b88e9359f
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/repos_invitations.go
@@ -0,0 +1,89 @@
+// Copyright 2016 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// RepositoryInvitation represents an invitation to collaborate on a repo.
+type RepositoryInvitation struct {
+	ID      *int64      `json:"id,omitempty"`
+	Repo    *Repository `json:"repository,omitempty"`
+	Invitee *User       `json:"invitee,omitempty"`
+	Inviter *User       `json:"inviter,omitempty"`
+
+	// Permissions represents the permissions that the associated user will have
+	// on the repository. Possible values are: "read", "write", "admin".
+	Permissions *string    `json:"permissions,omitempty"`
+	CreatedAt   *Timestamp `json:"created_at,omitempty"`
+	URL         *string    `json:"url,omitempty"`
+	HTMLURL     *string    `json:"html_url,omitempty"`
+}
+
+// ListInvitations lists all currently-open repository invitations.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/invitations/#list-invitations-for-a-repository
+func (s *RepositoriesService) ListInvitations(ctx context.Context, owner, repo string, opt *ListOptions) ([]*RepositoryInvitation, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/invitations", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	invites := []*RepositoryInvitation{}
+	resp, err := s.client.Do(ctx, req, &invites)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return invites, resp, nil
+}
+
+// DeleteInvitation deletes a repository invitation.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/invitations/#delete-a-repository-invitation
+func (s *RepositoriesService) DeleteInvitation(ctx context.Context, owner, repo string, invitationID int64) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/invitations/%v", owner, repo, invitationID)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// UpdateInvitation updates the permissions associated with a repository
+// invitation.
+//
+// permissions represents the permissions that the associated user will have
+// on the repository. Possible values are: "read", "write", "admin".
+//
+// GitHub API docs: https://developer.github.com/v3/repos/invitations/#update-a-repository-invitation
+func (s *RepositoriesService) UpdateInvitation(ctx context.Context, owner, repo string, invitationID int64, permissions string) (*RepositoryInvitation, *Response, error) {
+	opts := &struct {
+		Permissions string `json:"permissions"`
+	}{Permissions: permissions}
+	u := fmt.Sprintf("repos/%v/%v/invitations/%v", owner, repo, invitationID)
+	req, err := s.client.NewRequest("PATCH", u, opts)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	invite := &RepositoryInvitation{}
+	resp, err := s.client.Do(ctx, req, invite)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return invite, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/repos_keys.go b/vendor/github.com/google/go-github/v24/github/repos_keys.go
new file mode 100644
index 000000000..b484f8444
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/repos_keys.go
@@ -0,0 +1,111 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// The Key type is defined in users_keys.go
+
+// ListKeys lists the deploy keys for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/keys/#list
+func (s *RepositoriesService) ListKeys(ctx context.Context, owner string, repo string, opt *ListOptions) ([]*Key, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/keys", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var keys []*Key
+	resp, err := s.client.Do(ctx, req, &keys)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return keys, resp, nil
+}
+
+// GetKey fetches a single deploy key.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/keys/#get
+func (s *RepositoriesService) GetKey(ctx context.Context, owner string, repo string, id int64) (*Key, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/keys/%v", owner, repo, id)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	key := new(Key)
+	resp, err := s.client.Do(ctx, req, key)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return key, resp, nil
+}
+
+// CreateKey adds a deploy key for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/keys/#create
+func (s *RepositoriesService) CreateKey(ctx context.Context, owner string, repo string, key *Key) (*Key, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/keys", owner, repo)
+
+	req, err := s.client.NewRequest("POST", u, key)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	k := new(Key)
+	resp, err := s.client.Do(ctx, req, k)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return k, resp, nil
+}
+
+// EditKey edits a deploy key.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/keys/#edit
+func (s *RepositoriesService) EditKey(ctx context.Context, owner string, repo string, id int64, key *Key) (*Key, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/keys/%v", owner, repo, id)
+
+	req, err := s.client.NewRequest("PATCH", u, key)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	k := new(Key)
+	resp, err := s.client.Do(ctx, req, k)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return k, resp, nil
+}
+
+// DeleteKey deletes a deploy key.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/keys/#delete
+func (s *RepositoriesService) DeleteKey(ctx context.Context, owner string, repo string, id int64) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/keys/%v", owner, repo, id)
+
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/repos_merging.go b/vendor/github.com/google/go-github/v24/github/repos_merging.go
new file mode 100644
index 000000000..04383c1ae
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/repos_merging.go
@@ -0,0 +1,38 @@
+// Copyright 2014 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// RepositoryMergeRequest represents a request to merge a branch in a
+// repository.
+type RepositoryMergeRequest struct {
+	Base          *string `json:"base,omitempty"`
+	Head          *string `json:"head,omitempty"`
+	CommitMessage *string `json:"commit_message,omitempty"`
+}
+
+// Merge a branch in the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/merging/#perform-a-merge
+func (s *RepositoriesService) Merge(ctx context.Context, owner, repo string, request *RepositoryMergeRequest) (*RepositoryCommit, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/merges", owner, repo)
+	req, err := s.client.NewRequest("POST", u, request)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	commit := new(RepositoryCommit)
+	resp, err := s.client.Do(ctx, req, commit)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return commit, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/repos_pages.go b/vendor/github.com/google/go-github/v24/github/repos_pages.go
new file mode 100644
index 000000000..94a95f2b8
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/repos_pages.go
@@ -0,0 +1,143 @@
+// Copyright 2014 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// Pages represents a GitHub Pages site configuration.
+type Pages struct {
+	URL       *string `json:"url,omitempty"`
+	Status    *string `json:"status,omitempty"`
+	CNAME     *string `json:"cname,omitempty"`
+	Custom404 *bool   `json:"custom_404,omitempty"`
+	HTMLURL   *string `json:"html_url,omitempty"`
+}
+
+// PagesError represents a build error for a GitHub Pages site.
+type PagesError struct {
+	Message *string `json:"message,omitempty"`
+}
+
+// PagesBuild represents the build information for a GitHub Pages site.
+type PagesBuild struct {
+	URL       *string     `json:"url,omitempty"`
+	Status    *string     `json:"status,omitempty"`
+	Error     *PagesError `json:"error,omitempty"`
+	Pusher    *User       `json:"pusher,omitempty"`
+	Commit    *string     `json:"commit,omitempty"`
+	Duration  *int        `json:"duration,omitempty"`
+	CreatedAt *Timestamp  `json:"created_at,omitempty"`
+	UpdatedAt *Timestamp  `json:"updated_at,omitempty"`
+}
+
+// GetPagesInfo fetches information about a GitHub Pages site.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/pages/#get-information-about-a-pages-site
+func (s *RepositoriesService) GetPagesInfo(ctx context.Context, owner, repo string) (*Pages, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pages", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypePagesPreview)
+
+	site := new(Pages)
+	resp, err := s.client.Do(ctx, req, site)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return site, resp, nil
+}
+
+// ListPagesBuilds lists the builds for a GitHub Pages site.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/pages/#list-pages-builds
+func (s *RepositoriesService) ListPagesBuilds(ctx context.Context, owner, repo string, opt *ListOptions) ([]*PagesBuild, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pages/builds", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var pages []*PagesBuild
+	resp, err := s.client.Do(ctx, req, &pages)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return pages, resp, nil
+}
+
+// GetLatestPagesBuild fetches the latest build information for a GitHub pages site.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/pages/#list-latest-pages-build
+func (s *RepositoriesService) GetLatestPagesBuild(ctx context.Context, owner, repo string) (*PagesBuild, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pages/builds/latest", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	build := new(PagesBuild)
+	resp, err := s.client.Do(ctx, req, build)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return build, resp, nil
+}
+
+// GetPageBuild fetches the specific build information for a GitHub pages site.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/pages/#list-a-specific-pages-build
+func (s *RepositoriesService) GetPageBuild(ctx context.Context, owner, repo string, id int64) (*PagesBuild, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pages/builds/%v", owner, repo, id)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	build := new(PagesBuild)
+	resp, err := s.client.Do(ctx, req, build)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return build, resp, nil
+}
+
+// RequestPageBuild requests a build of a GitHub Pages site without needing to push new commit.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/pages/#request-a-page-build
+func (s *RepositoriesService) RequestPageBuild(ctx context.Context, owner, repo string) (*PagesBuild, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pages/builds", owner, repo)
+	req, err := s.client.NewRequest("POST", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypePagesPreview)
+
+	build := new(PagesBuild)
+	resp, err := s.client.Do(ctx, req, build)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return build, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/repos_prereceive_hooks.go b/vendor/github.com/google/go-github/v24/github/repos_prereceive_hooks.go
new file mode 100644
index 000000000..cab09f747
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/repos_prereceive_hooks.go
@@ -0,0 +1,110 @@
+// Copyright 2018 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// PreReceiveHook represents a GitHub pre-receive hook for a repository.
+type PreReceiveHook struct {
+	ID          *int64  `json:"id,omitempty"`
+	Name        *string `json:"name,omitempty"`
+	Enforcement *string `json:"enforcement,omitempty"`
+	ConfigURL   *string `json:"configuration_url,omitempty"`
+}
+
+func (p PreReceiveHook) String() string {
+	return Stringify(p)
+}
+
+// ListPreReceiveHooks lists all pre-receive hooks for the specified repository.
+//
+// GitHub API docs: https://developer.github.com/enterprise/2.13/v3/repos/pre_receive_hooks/#list-pre-receive-hooks
+func (s *RepositoriesService) ListPreReceiveHooks(ctx context.Context, owner, repo string, opt *ListOptions) ([]*PreReceiveHook, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pre-receive-hooks", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypePreReceiveHooksPreview)
+
+	var hooks []*PreReceiveHook
+	resp, err := s.client.Do(ctx, req, &hooks)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return hooks, resp, nil
+}
+
+// GetPreReceiveHook returns a single specified pre-receive hook.
+//
+// GitHub API docs: https://developer.github.com/enterprise/2.13/v3/repos/pre_receive_hooks/#get-a-single-pre-receive-hook
+func (s *RepositoriesService) GetPreReceiveHook(ctx context.Context, owner, repo string, id int64) (*PreReceiveHook, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pre-receive-hooks/%d", owner, repo, id)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypePreReceiveHooksPreview)
+
+	h := new(PreReceiveHook)
+	resp, err := s.client.Do(ctx, req, h)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return h, resp, nil
+}
+
+// UpdatePreReceiveHook updates a specified pre-receive hook.
+//
+// GitHub API docs: https://developer.github.com/enterprise/2.13/v3/repos/pre_receive_hooks/#update-pre-receive-hook-enforcement
+func (s *RepositoriesService) UpdatePreReceiveHook(ctx context.Context, owner, repo string, id int64, hook *PreReceiveHook) (*PreReceiveHook, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pre-receive-hooks/%d", owner, repo, id)
+	req, err := s.client.NewRequest("PATCH", u, hook)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypePreReceiveHooksPreview)
+
+	h := new(PreReceiveHook)
+	resp, err := s.client.Do(ctx, req, h)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return h, resp, nil
+}
+
+// DeletePreReceiveHook deletes a specified pre-receive hook.
+//
+// GitHub API docs: https://developer.github.com/enterprise/2.13/v3/repos/pre_receive_hooks/#remove-enforcement-overrides-for-a-pre-receive-hook
+func (s *RepositoriesService) DeletePreReceiveHook(ctx context.Context, owner, repo string, id int64) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pre-receive-hooks/%d", owner, repo, id)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypePreReceiveHooksPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/repos_projects.go b/vendor/github.com/google/go-github/v24/github/repos_projects.go
new file mode 100644
index 000000000..d6486d293
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/repos_projects.go
@@ -0,0 +1,69 @@
+// Copyright 2017 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// ProjectListOptions specifies the optional parameters to the
+// OrganizationsService.ListProjects and RepositoriesService.ListProjects methods.
+type ProjectListOptions struct {
+	// Indicates the state of the projects to return. Can be either open, closed, or all. Default: open
+	State string `url:"state,omitempty"`
+
+	ListOptions
+}
+
+// ListProjects lists the projects for a repo.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/#list-repository-projects
+func (s *RepositoriesService) ListProjects(ctx context.Context, owner, repo string, opt *ProjectListOptions) ([]*Project, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/projects", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	var projects []*Project
+	resp, err := s.client.Do(ctx, req, &projects)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return projects, resp, nil
+}
+
+// CreateProject creates a GitHub Project for the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/#create-a-repository-project
+func (s *RepositoriesService) CreateProject(ctx context.Context, owner, repo string, opt *ProjectOptions) (*Project, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/projects", owner, repo)
+	req, err := s.client.NewRequest("POST", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	project := &Project{}
+	resp, err := s.client.Do(ctx, req, project)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return project, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/repos_releases.go b/vendor/github.com/google/go-github/v24/github/repos_releases.go
new file mode 100644
index 000000000..5c0a1cea8
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/repos_releases.go
@@ -0,0 +1,374 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"io"
+	"mime"
+	"net/http"
+	"os"
+	"path/filepath"
+	"strings"
+)
+
+// RepositoryRelease represents a GitHub release in a repository.
+type RepositoryRelease struct {
+	TagName         *string `json:"tag_name,omitempty"`
+	TargetCommitish *string `json:"target_commitish,omitempty"`
+	Name            *string `json:"name,omitempty"`
+	Body            *string `json:"body,omitempty"`
+	Draft           *bool   `json:"draft,omitempty"`
+	Prerelease      *bool   `json:"prerelease,omitempty"`
+
+	// The following fields are not used in CreateRelease or EditRelease:
+	ID          *int64         `json:"id,omitempty"`
+	CreatedAt   *Timestamp     `json:"created_at,omitempty"`
+	PublishedAt *Timestamp     `json:"published_at,omitempty"`
+	URL         *string        `json:"url,omitempty"`
+	HTMLURL     *string        `json:"html_url,omitempty"`
+	AssetsURL   *string        `json:"assets_url,omitempty"`
+	Assets      []ReleaseAsset `json:"assets,omitempty"`
+	UploadURL   *string        `json:"upload_url,omitempty"`
+	ZipballURL  *string        `json:"zipball_url,omitempty"`
+	TarballURL  *string        `json:"tarball_url,omitempty"`
+	Author      *User          `json:"author,omitempty"`
+	NodeID      *string        `json:"node_id,omitempty"`
+}
+
+func (r RepositoryRelease) String() string {
+	return Stringify(r)
+}
+
+// ReleaseAsset represents a GitHub release asset in a repository.
+type ReleaseAsset struct {
+	ID                 *int64     `json:"id,omitempty"`
+	URL                *string    `json:"url,omitempty"`
+	Name               *string    `json:"name,omitempty"`
+	Label              *string    `json:"label,omitempty"`
+	State              *string    `json:"state,omitempty"`
+	ContentType        *string    `json:"content_type,omitempty"`
+	Size               *int       `json:"size,omitempty"`
+	DownloadCount      *int       `json:"download_count,omitempty"`
+	CreatedAt          *Timestamp `json:"created_at,omitempty"`
+	UpdatedAt          *Timestamp `json:"updated_at,omitempty"`
+	BrowserDownloadURL *string    `json:"browser_download_url,omitempty"`
+	Uploader           *User      `json:"uploader,omitempty"`
+	NodeID             *string    `json:"node_id,omitempty"`
+}
+
+func (r ReleaseAsset) String() string {
+	return Stringify(r)
+}
+
+// ListReleases lists the releases for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/releases/#list-releases-for-a-repository
+func (s *RepositoriesService) ListReleases(ctx context.Context, owner, repo string, opt *ListOptions) ([]*RepositoryRelease, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/releases", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var releases []*RepositoryRelease
+	resp, err := s.client.Do(ctx, req, &releases)
+	if err != nil {
+		return nil, resp, err
+	}
+	return releases, resp, nil
+}
+
+// GetRelease fetches a single release.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/releases/#get-a-single-release
+func (s *RepositoriesService) GetRelease(ctx context.Context, owner, repo string, id int64) (*RepositoryRelease, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/releases/%d", owner, repo, id)
+	return s.getSingleRelease(ctx, u)
+}
+
+// GetLatestRelease fetches the latest published release for the repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/releases/#get-the-latest-release
+func (s *RepositoriesService) GetLatestRelease(ctx context.Context, owner, repo string) (*RepositoryRelease, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/releases/latest", owner, repo)
+	return s.getSingleRelease(ctx, u)
+}
+
+// GetReleaseByTag fetches a release with the specified tag.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/releases/#get-a-release-by-tag-name
+func (s *RepositoriesService) GetReleaseByTag(ctx context.Context, owner, repo, tag string) (*RepositoryRelease, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/releases/tags/%s", owner, repo, tag)
+	return s.getSingleRelease(ctx, u)
+}
+
+func (s *RepositoriesService) getSingleRelease(ctx context.Context, url string) (*RepositoryRelease, *Response, error) {
+	req, err := s.client.NewRequest("GET", url, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	release := new(RepositoryRelease)
+	resp, err := s.client.Do(ctx, req, release)
+	if err != nil {
+		return nil, resp, err
+	}
+	return release, resp, nil
+}
+
+// repositoryReleaseRequest is a subset of RepositoryRelease and
+// is used internally by CreateRelease and EditRelease to pass
+// only the known fields for these endpoints.
+//
+// See https://github.com/google/go-github/issues/992 for more
+// information.
+type repositoryReleaseRequest struct {
+	TagName         *string `json:"tag_name,omitempty"`
+	TargetCommitish *string `json:"target_commitish,omitempty"`
+	Name            *string `json:"name,omitempty"`
+	Body            *string `json:"body,omitempty"`
+	Draft           *bool   `json:"draft,omitempty"`
+	Prerelease      *bool   `json:"prerelease,omitempty"`
+}
+
+// CreateRelease adds a new release for a repository.
+//
+// Note that only a subset of the release fields are used.
+// See RepositoryRelease for more information.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/releases/#create-a-release
+func (s *RepositoriesService) CreateRelease(ctx context.Context, owner, repo string, release *RepositoryRelease) (*RepositoryRelease, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/releases", owner, repo)
+
+	releaseReq := &repositoryReleaseRequest{
+		TagName:         release.TagName,
+		TargetCommitish: release.TargetCommitish,
+		Name:            release.Name,
+		Body:            release.Body,
+		Draft:           release.Draft,
+		Prerelease:      release.Prerelease,
+	}
+
+	req, err := s.client.NewRequest("POST", u, releaseReq)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	r := new(RepositoryRelease)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+	return r, resp, nil
+}
+
+// EditRelease edits a repository release.
+//
+// Note that only a subset of the release fields are used.
+// See RepositoryRelease for more information.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/releases/#edit-a-release
+func (s *RepositoriesService) EditRelease(ctx context.Context, owner, repo string, id int64, release *RepositoryRelease) (*RepositoryRelease, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/releases/%d", owner, repo, id)
+
+	releaseReq := &repositoryReleaseRequest{
+		TagName:         release.TagName,
+		TargetCommitish: release.TargetCommitish,
+		Name:            release.Name,
+		Body:            release.Body,
+		Draft:           release.Draft,
+		Prerelease:      release.Prerelease,
+	}
+
+	req, err := s.client.NewRequest("PATCH", u, releaseReq)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	r := new(RepositoryRelease)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+	return r, resp, nil
+}
+
+// DeleteRelease delete a single release from a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/releases/#delete-a-release
+func (s *RepositoriesService) DeleteRelease(ctx context.Context, owner, repo string, id int64) (*Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/releases/%d", owner, repo, id)
+
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
+
+// ListReleaseAssets lists the release's assets.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/releases/#list-assets-for-a-release
+func (s *RepositoriesService) ListReleaseAssets(ctx context.Context, owner, repo string, id int64, opt *ListOptions) ([]*ReleaseAsset, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/releases/%d/assets", owner, repo, id)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var assets []*ReleaseAsset
+	resp, err := s.client.Do(ctx, req, &assets)
+	if err != nil {
+		return nil, resp, err
+	}
+	return assets, resp, nil
+}
+
+// GetReleaseAsset fetches a single release asset.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/releases/#get-a-single-release-asset
+func (s *RepositoriesService) GetReleaseAsset(ctx context.Context, owner, repo string, id int64) (*ReleaseAsset, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	asset := new(ReleaseAsset)
+	resp, err := s.client.Do(ctx, req, asset)
+	if err != nil {
+		return nil, resp, err
+	}
+	return asset, resp, nil
+}
+
+// DownloadReleaseAsset downloads a release asset or returns a redirect URL.
+//
+// DownloadReleaseAsset returns an io.ReadCloser that reads the contents of the
+// specified release asset. It is the caller's responsibility to close the ReadCloser.
+// If a redirect is returned, the redirect URL will be returned as a string instead
+// of the io.ReadCloser. Exactly one of rc and redirectURL will be zero.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/releases/#get-a-single-release-asset
+func (s *RepositoriesService) DownloadReleaseAsset(ctx context.Context, owner, repo string, id int64) (rc io.ReadCloser, redirectURL string, err error) {
+	u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, "", err
+	}
+	req.Header.Set("Accept", defaultMediaType)
+
+	s.client.clientMu.Lock()
+	defer s.client.clientMu.Unlock()
+
+	var loc string
+	saveRedirect := s.client.client.CheckRedirect
+	s.client.client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
+		loc = req.URL.String()
+		return errors.New("disable redirect")
+	}
+	defer func() { s.client.client.CheckRedirect = saveRedirect }()
+
+	req = withContext(ctx, req)
+	resp, err := s.client.client.Do(req)
+	if err != nil {
+		if !strings.Contains(err.Error(), "disable redirect") {
+			return nil, "", err
+		}
+		return nil, loc, nil // Intentionally return no error with valid redirect URL.
+	}
+
+	if err := CheckResponse(resp); err != nil {
+		resp.Body.Close()
+		return nil, "", err
+	}
+
+	return resp.Body, "", nil
+}
+
+// EditReleaseAsset edits a repository release asset.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/releases/#edit-a-release-asset
+func (s *RepositoriesService) EditReleaseAsset(ctx context.Context, owner, repo string, id int64, release *ReleaseAsset) (*ReleaseAsset, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id)
+
+	req, err := s.client.NewRequest("PATCH", u, release)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	asset := new(ReleaseAsset)
+	resp, err := s.client.Do(ctx, req, asset)
+	if err != nil {
+		return nil, resp, err
+	}
+	return asset, resp, nil
+}
+
+// DeleteReleaseAsset delete a single release asset from a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/releases/#delete-a-release-asset
+func (s *RepositoriesService) DeleteReleaseAsset(ctx context.Context, owner, repo string, id int64) (*Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id)
+
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
+
+// UploadReleaseAsset creates an asset by uploading a file into a release repository.
+// To upload assets that cannot be represented by an os.File, call NewUploadRequest directly.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/releases/#upload-a-release-asset
+func (s *RepositoriesService) UploadReleaseAsset(ctx context.Context, owner, repo string, id int64, opt *UploadOptions, file *os.File) (*ReleaseAsset, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/releases/%d/assets", owner, repo, id)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	stat, err := file.Stat()
+	if err != nil {
+		return nil, nil, err
+	}
+	if stat.IsDir() {
+		return nil, nil, errors.New("the asset to upload can't be a directory")
+	}
+
+	mediaType := mime.TypeByExtension(filepath.Ext(file.Name()))
+	if opt.MediaType != "" {
+		mediaType = opt.MediaType
+	}
+
+	req, err := s.client.NewUploadRequest(u, file, stat.Size(), mediaType)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	asset := new(ReleaseAsset)
+	resp, err := s.client.Do(ctx, req, asset)
+	if err != nil {
+		return nil, resp, err
+	}
+	return asset, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/repos_stats.go b/vendor/github.com/google/go-github/v24/github/repos_stats.go
new file mode 100644
index 000000000..bb355aead
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/repos_stats.go
@@ -0,0 +1,226 @@
+// Copyright 2014 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// ContributorStats represents a contributor to a repository and their
+// weekly contributions to a given repo.
+type ContributorStats struct {
+	Author *Contributor  `json:"author,omitempty"`
+	Total  *int          `json:"total,omitempty"`
+	Weeks  []WeeklyStats `json:"weeks,omitempty"`
+}
+
+func (c ContributorStats) String() string {
+	return Stringify(c)
+}
+
+// WeeklyStats represents the number of additions, deletions and commits
+// a Contributor made in a given week.
+type WeeklyStats struct {
+	Week      *Timestamp `json:"w,omitempty"`
+	Additions *int       `json:"a,omitempty"`
+	Deletions *int       `json:"d,omitempty"`
+	Commits   *int       `json:"c,omitempty"`
+}
+
+func (w WeeklyStats) String() string {
+	return Stringify(w)
+}
+
+// ListContributorsStats gets a repo's contributor list with additions,
+// deletions and commit counts.
+//
+// If this is the first time these statistics are requested for the given
+// repository, this method will return an *AcceptedError and a status code of
+// 202. This is because this is the status that GitHub returns to signify that
+// it is now computing the requested statistics. A follow up request, after a
+// delay of a second or so, should result in a successful request.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/statistics/#contributors
+func (s *RepositoriesService) ListContributorsStats(ctx context.Context, owner, repo string) ([]*ContributorStats, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/stats/contributors", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var contributorStats []*ContributorStats
+	resp, err := s.client.Do(ctx, req, &contributorStats)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return contributorStats, resp, nil
+}
+
+// WeeklyCommitActivity represents the weekly commit activity for a repository.
+// The days array is a group of commits per day, starting on Sunday.
+type WeeklyCommitActivity struct {
+	Days  []int      `json:"days,omitempty"`
+	Total *int       `json:"total,omitempty"`
+	Week  *Timestamp `json:"week,omitempty"`
+}
+
+func (w WeeklyCommitActivity) String() string {
+	return Stringify(w)
+}
+
+// ListCommitActivity returns the last year of commit activity
+// grouped by week. The days array is a group of commits per day,
+// starting on Sunday.
+//
+// If this is the first time these statistics are requested for the given
+// repository, this method will return an *AcceptedError and a status code of
+// 202. This is because this is the status that GitHub returns to signify that
+// it is now computing the requested statistics. A follow up request, after a
+// delay of a second or so, should result in a successful request.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/statistics/#commit-activity
+func (s *RepositoriesService) ListCommitActivity(ctx context.Context, owner, repo string) ([]*WeeklyCommitActivity, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/stats/commit_activity", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var weeklyCommitActivity []*WeeklyCommitActivity
+	resp, err := s.client.Do(ctx, req, &weeklyCommitActivity)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return weeklyCommitActivity, resp, nil
+}
+
+// ListCodeFrequency returns a weekly aggregate of the number of additions and
+// deletions pushed to a repository. Returned WeeklyStats will contain
+// additions and deletions, but not total commits.
+//
+// If this is the first time these statistics are requested for the given
+// repository, this method will return an *AcceptedError and a status code of
+// 202. This is because this is the status that GitHub returns to signify that
+// it is now computing the requested statistics. A follow up request, after a
+// delay of a second or so, should result in a successful request.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/statistics/#code-frequency
+func (s *RepositoriesService) ListCodeFrequency(ctx context.Context, owner, repo string) ([]*WeeklyStats, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/stats/code_frequency", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var weeks [][]int
+	resp, err := s.client.Do(ctx, req, &weeks)
+
+	// convert int slices into WeeklyStats
+	var stats []*WeeklyStats
+	for _, week := range weeks {
+		if len(week) != 3 {
+			continue
+		}
+		stat := &WeeklyStats{
+			Week:      &Timestamp{time.Unix(int64(week[0]), 0)},
+			Additions: Int(week[1]),
+			Deletions: Int(week[2]),
+		}
+		stats = append(stats, stat)
+	}
+
+	return stats, resp, err
+}
+
+// RepositoryParticipation is the number of commits by everyone
+// who has contributed to the repository (including the owner)
+// as well as the number of commits by the owner themself.
+type RepositoryParticipation struct {
+	All   []int `json:"all,omitempty"`
+	Owner []int `json:"owner,omitempty"`
+}
+
+func (r RepositoryParticipation) String() string {
+	return Stringify(r)
+}
+
+// ListParticipation returns the total commit counts for the 'owner'
+// and total commit counts in 'all'. 'all' is everyone combined,
+// including the 'owner' in the last 52 weeks. If you’d like to get
+// the commit counts for non-owners, you can subtract 'all' from 'owner'.
+//
+// The array order is oldest week (index 0) to most recent week.
+//
+// If this is the first time these statistics are requested for the given
+// repository, this method will return an *AcceptedError and a status code of
+// 202. This is because this is the status that GitHub returns to signify that
+// it is now computing the requested statistics. A follow up request, after a
+// delay of a second or so, should result in a successful request.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/statistics/#participation
+func (s *RepositoriesService) ListParticipation(ctx context.Context, owner, repo string) (*RepositoryParticipation, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/stats/participation", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	participation := new(RepositoryParticipation)
+	resp, err := s.client.Do(ctx, req, participation)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return participation, resp, nil
+}
+
+// PunchCard represents the number of commits made during a given hour of a
+// day of the week.
+type PunchCard struct {
+	Day     *int // Day of the week (0-6: =Sunday - Saturday).
+	Hour    *int // Hour of day (0-23).
+	Commits *int // Number of commits.
+}
+
+// ListPunchCard returns the number of commits per hour in each day.
+//
+// If this is the first time these statistics are requested for the given
+// repository, this method will return an *AcceptedError and a status code of
+// 202. This is because this is the status that GitHub returns to signify that
+// it is now computing the requested statistics. A follow up request, after a
+// delay of a second or so, should result in a successful request.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/statistics/#punch-card
+func (s *RepositoriesService) ListPunchCard(ctx context.Context, owner, repo string) ([]*PunchCard, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/stats/punch_card", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var results [][]int
+	resp, err := s.client.Do(ctx, req, &results)
+
+	// convert int slices into Punchcards
+	var cards []*PunchCard
+	for _, result := range results {
+		if len(result) != 3 {
+			continue
+		}
+		card := &PunchCard{
+			Day:     Int(result[0]),
+			Hour:    Int(result[1]),
+			Commits: Int(result[2]),
+		}
+		cards = append(cards, card)
+	}
+
+	return cards, resp, err
+}
diff --git a/vendor/github.com/google/go-github/v24/github/repos_statuses.go b/vendor/github.com/google/go-github/v24/github/repos_statuses.go
new file mode 100644
index 000000000..c889b31dd
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/repos_statuses.go
@@ -0,0 +1,130 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"net/url"
+	"time"
+)
+
+// RepoStatus represents the status of a repository at a particular reference.
+type RepoStatus struct {
+	ID  *int64  `json:"id,omitempty"`
+	URL *string `json:"url,omitempty"`
+
+	// State is the current state of the repository. Possible values are:
+	// pending, success, error, or failure.
+	State *string `json:"state,omitempty"`
+
+	// TargetURL is the URL of the page representing this status. It will be
+	// linked from the GitHub UI to allow users to see the source of the status.
+	TargetURL *string `json:"target_url,omitempty"`
+
+	// Description is a short high level summary of the status.
+	Description *string `json:"description,omitempty"`
+
+	// A string label to differentiate this status from the statuses of other systems.
+	Context *string `json:"context,omitempty"`
+
+	Creator   *User      `json:"creator,omitempty"`
+	CreatedAt *time.Time `json:"created_at,omitempty"`
+	UpdatedAt *time.Time `json:"updated_at,omitempty"`
+}
+
+func (r RepoStatus) String() string {
+	return Stringify(r)
+}
+
+// ListStatuses lists the statuses of a repository at the specified
+// reference. ref can be a SHA, a branch name, or a tag name.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/statuses/#list-statuses-for-a-specific-ref
+func (s *RepositoriesService) ListStatuses(ctx context.Context, owner, repo, ref string, opt *ListOptions) ([]*RepoStatus, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/commits/%v/statuses", owner, repo, url.QueryEscape(ref))
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var statuses []*RepoStatus
+	resp, err := s.client.Do(ctx, req, &statuses)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return statuses, resp, nil
+}
+
+// CreateStatus creates a new status for a repository at the specified
+// reference. Ref can be a SHA, a branch name, or a tag name.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/statuses/#create-a-status
+func (s *RepositoriesService) CreateStatus(ctx context.Context, owner, repo, ref string, status *RepoStatus) (*RepoStatus, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/statuses/%v", owner, repo, url.QueryEscape(ref))
+	req, err := s.client.NewRequest("POST", u, status)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	repoStatus := new(RepoStatus)
+	resp, err := s.client.Do(ctx, req, repoStatus)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return repoStatus, resp, nil
+}
+
+// CombinedStatus represents the combined status of a repository at a particular reference.
+type CombinedStatus struct {
+	// State is the combined state of the repository. Possible values are:
+	// failure, pending, or success.
+	State *string `json:"state,omitempty"`
+
+	Name       *string      `json:"name,omitempty"`
+	SHA        *string      `json:"sha,omitempty"`
+	TotalCount *int         `json:"total_count,omitempty"`
+	Statuses   []RepoStatus `json:"statuses,omitempty"`
+
+	CommitURL     *string `json:"commit_url,omitempty"`
+	RepositoryURL *string `json:"repository_url,omitempty"`
+}
+
+func (s CombinedStatus) String() string {
+	return Stringify(s)
+}
+
+// GetCombinedStatus returns the combined status of a repository at the specified
+// reference. ref can be a SHA, a branch name, or a tag name.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref
+func (s *RepositoriesService) GetCombinedStatus(ctx context.Context, owner, repo, ref string, opt *ListOptions) (*CombinedStatus, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/commits/%v/status", owner, repo, url.QueryEscape(ref))
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	status := new(CombinedStatus)
+	resp, err := s.client.Do(ctx, req, status)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return status, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/repos_traffic.go b/vendor/github.com/google/go-github/v24/github/repos_traffic.go
new file mode 100644
index 000000000..fb1c97648
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/repos_traffic.go
@@ -0,0 +1,141 @@
+// Copyright 2016 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// TrafficReferrer represent information about traffic from a referrer .
+type TrafficReferrer struct {
+	Referrer *string `json:"referrer,omitempty"`
+	Count    *int    `json:"count,omitempty"`
+	Uniques  *int    `json:"uniques,omitempty"`
+}
+
+// TrafficPath represent information about the traffic on a path of the repo.
+type TrafficPath struct {
+	Path    *string `json:"path,omitempty"`
+	Title   *string `json:"title,omitempty"`
+	Count   *int    `json:"count,omitempty"`
+	Uniques *int    `json:"uniques,omitempty"`
+}
+
+// TrafficData represent information about a specific timestamp in views or clones list.
+type TrafficData struct {
+	Timestamp *Timestamp `json:"timestamp,omitempty"`
+	Count     *int       `json:"count,omitempty"`
+	Uniques   *int       `json:"uniques,omitempty"`
+}
+
+// TrafficViews represent information about the number of views in the last 14 days.
+type TrafficViews struct {
+	Views   []*TrafficData `json:"views,omitempty"`
+	Count   *int           `json:"count,omitempty"`
+	Uniques *int           `json:"uniques,omitempty"`
+}
+
+// TrafficClones represent information about the number of clones in the last 14 days.
+type TrafficClones struct {
+	Clones  []*TrafficData `json:"clones,omitempty"`
+	Count   *int           `json:"count,omitempty"`
+	Uniques *int           `json:"uniques,omitempty"`
+}
+
+// TrafficBreakdownOptions specifies the parameters to methods that support breakdown per day or week.
+// Can be one of: day, week. Default: day.
+type TrafficBreakdownOptions struct {
+	Per string `url:"per,omitempty"`
+}
+
+// ListTrafficReferrers list the top 10 referrers over the last 14 days.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/traffic/#list-referrers
+func (s *RepositoriesService) ListTrafficReferrers(ctx context.Context, owner, repo string) ([]*TrafficReferrer, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/traffic/popular/referrers", owner, repo)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var trafficReferrers []*TrafficReferrer
+	resp, err := s.client.Do(ctx, req, &trafficReferrers)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return trafficReferrers, resp, nil
+}
+
+// ListTrafficPaths list the top 10 popular content over the last 14 days.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/traffic/#list-paths
+func (s *RepositoriesService) ListTrafficPaths(ctx context.Context, owner, repo string) ([]*TrafficPath, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/traffic/popular/paths", owner, repo)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var paths []*TrafficPath
+	resp, err := s.client.Do(ctx, req, &paths)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return paths, resp, nil
+}
+
+// ListTrafficViews get total number of views for the last 14 days and breaks it down either per day or week.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/traffic/#views
+func (s *RepositoriesService) ListTrafficViews(ctx context.Context, owner, repo string, opt *TrafficBreakdownOptions) (*TrafficViews, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/traffic/views", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	trafficViews := new(TrafficViews)
+	resp, err := s.client.Do(ctx, req, &trafficViews)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return trafficViews, resp, nil
+}
+
+// ListTrafficClones get total number of clones for the last 14 days and breaks it down either per day or week for the last 14 days.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/traffic/#views
+func (s *RepositoriesService) ListTrafficClones(ctx context.Context, owner, repo string, opt *TrafficBreakdownOptions) (*TrafficClones, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/traffic/clones", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	trafficClones := new(TrafficClones)
+	resp, err := s.client.Do(ctx, req, &trafficClones)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return trafficClones, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/search.go b/vendor/github.com/google/go-github/v24/github/search.go
new file mode 100644
index 000000000..24156f318
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/search.go
@@ -0,0 +1,258 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"strconv"
+
+	qs "github.com/google/go-querystring/query"
+)
+
+// SearchService provides access to the search related functions
+// in the GitHub API.
+//
+// Each method takes a query string defining the search keywords and any search qualifiers.
+// For example, when searching issues, the query "gopher is:issue language:go" will search
+// for issues containing the word "gopher" in Go repositories. The method call
+//   opts :=  &github.SearchOptions{Sort: "created", Order: "asc"}
+//   cl.Search.Issues(ctx, "gopher is:issue language:go", opts)
+// will search for such issues, sorting by creation date in ascending order
+// (i.e., oldest first).
+//
+// GitHub API docs: https://developer.github.com/v3/search/
+type SearchService service
+
+// SearchOptions specifies optional parameters to the SearchService methods.
+type SearchOptions struct {
+	// How to sort the search results. Possible values are:
+	//   - for repositories: stars, fork, updated
+	//   - for commits: author-date, committer-date
+	//   - for code: indexed
+	//   - for issues: comments, created, updated
+	//   - for users: followers, repositories, joined
+	//
+	// Default is to sort by best match.
+	Sort string `url:"sort,omitempty"`
+
+	// Sort order if sort parameter is provided. Possible values are: asc,
+	// desc. Default is desc.
+	Order string `url:"order,omitempty"`
+
+	// Whether to retrieve text match metadata with a query
+	TextMatch bool `url:"-"`
+
+	ListOptions
+}
+
+// Common search parameters.
+type searchParameters struct {
+	Query        string
+	RepositoryID *int64 // Sent if non-nil.
+}
+
+// RepositoriesSearchResult represents the result of a repositories search.
+type RepositoriesSearchResult struct {
+	Total             *int         `json:"total_count,omitempty"`
+	IncompleteResults *bool        `json:"incomplete_results,omitempty"`
+	Repositories      []Repository `json:"items,omitempty"`
+}
+
+// Repositories searches repositories via various criteria.
+//
+// GitHub API docs: https://developer.github.com/v3/search/#search-repositories
+func (s *SearchService) Repositories(ctx context.Context, query string, opt *SearchOptions) (*RepositoriesSearchResult, *Response, error) {
+	result := new(RepositoriesSearchResult)
+	resp, err := s.search(ctx, "repositories", &searchParameters{Query: query}, opt, result)
+	return result, resp, err
+}
+
+// CommitsSearchResult represents the result of a commits search.
+type CommitsSearchResult struct {
+	Total             *int            `json:"total_count,omitempty"`
+	IncompleteResults *bool           `json:"incomplete_results,omitempty"`
+	Commits           []*CommitResult `json:"items,omitempty"`
+}
+
+// CommitResult represents a commit object as returned in commit search endpoint response.
+type CommitResult struct {
+	SHA         *string   `json:"sha,omitempty"`
+	Commit      *Commit   `json:"commit,omitempty"`
+	Author      *User     `json:"author,omitempty"`
+	Committer   *User     `json:"committer,omitempty"`
+	Parents     []*Commit `json:"parents,omitempty"`
+	HTMLURL     *string   `json:"html_url,omitempty"`
+	URL         *string   `json:"url,omitempty"`
+	CommentsURL *string   `json:"comments_url,omitempty"`
+
+	Repository *Repository `json:"repository,omitempty"`
+	Score      *float64    `json:"score,omitempty"`
+}
+
+// Commits searches commits via various criteria.
+//
+// GitHub API docs: https://developer.github.com/v3/search/#search-commits
+func (s *SearchService) Commits(ctx context.Context, query string, opt *SearchOptions) (*CommitsSearchResult, *Response, error) {
+	result := new(CommitsSearchResult)
+	resp, err := s.search(ctx, "commits", &searchParameters{Query: query}, opt, result)
+	return result, resp, err
+}
+
+// IssuesSearchResult represents the result of an issues search.
+type IssuesSearchResult struct {
+	Total             *int    `json:"total_count,omitempty"`
+	IncompleteResults *bool   `json:"incomplete_results,omitempty"`
+	Issues            []Issue `json:"items,omitempty"`
+}
+
+// Issues searches issues via various criteria.
+//
+// GitHub API docs: https://developer.github.com/v3/search/#search-issues
+func (s *SearchService) Issues(ctx context.Context, query string, opt *SearchOptions) (*IssuesSearchResult, *Response, error) {
+	result := new(IssuesSearchResult)
+	resp, err := s.search(ctx, "issues", &searchParameters{Query: query}, opt, result)
+	return result, resp, err
+}
+
+// UsersSearchResult represents the result of a users search.
+type UsersSearchResult struct {
+	Total             *int   `json:"total_count,omitempty"`
+	IncompleteResults *bool  `json:"incomplete_results,omitempty"`
+	Users             []User `json:"items,omitempty"`
+}
+
+// Users searches users via various criteria.
+//
+// GitHub API docs: https://developer.github.com/v3/search/#search-users
+func (s *SearchService) Users(ctx context.Context, query string, opt *SearchOptions) (*UsersSearchResult, *Response, error) {
+	result := new(UsersSearchResult)
+	resp, err := s.search(ctx, "users", &searchParameters{Query: query}, opt, result)
+	return result, resp, err
+}
+
+// Match represents a single text match.
+type Match struct {
+	Text    *string `json:"text,omitempty"`
+	Indices []int   `json:"indices,omitempty"`
+}
+
+// TextMatch represents a text match for a SearchResult
+type TextMatch struct {
+	ObjectURL  *string `json:"object_url,omitempty"`
+	ObjectType *string `json:"object_type,omitempty"`
+	Property   *string `json:"property,omitempty"`
+	Fragment   *string `json:"fragment,omitempty"`
+	Matches    []Match `json:"matches,omitempty"`
+}
+
+func (tm TextMatch) String() string {
+	return Stringify(tm)
+}
+
+// CodeSearchResult represents the result of a code search.
+type CodeSearchResult struct {
+	Total             *int         `json:"total_count,omitempty"`
+	IncompleteResults *bool        `json:"incomplete_results,omitempty"`
+	CodeResults       []CodeResult `json:"items,omitempty"`
+}
+
+// CodeResult represents a single search result.
+type CodeResult struct {
+	Name        *string     `json:"name,omitempty"`
+	Path        *string     `json:"path,omitempty"`
+	SHA         *string     `json:"sha,omitempty"`
+	HTMLURL     *string     `json:"html_url,omitempty"`
+	Repository  *Repository `json:"repository,omitempty"`
+	TextMatches []TextMatch `json:"text_matches,omitempty"`
+}
+
+func (c CodeResult) String() string {
+	return Stringify(c)
+}
+
+// Code searches code via various criteria.
+//
+// GitHub API docs: https://developer.github.com/v3/search/#search-code
+func (s *SearchService) Code(ctx context.Context, query string, opt *SearchOptions) (*CodeSearchResult, *Response, error) {
+	result := new(CodeSearchResult)
+	resp, err := s.search(ctx, "code", &searchParameters{Query: query}, opt, result)
+	return result, resp, err
+}
+
+// LabelsSearchResult represents the result of a code search.
+type LabelsSearchResult struct {
+	Total             *int           `json:"total_count,omitempty"`
+	IncompleteResults *bool          `json:"incomplete_results,omitempty"`
+	Labels            []*LabelResult `json:"items,omitempty"`
+}
+
+// LabelResult represents a single search result.
+type LabelResult struct {
+	ID          *int64   `json:"id,omitempty"`
+	URL         *string  `json:"url,omitempty"`
+	Name        *string  `json:"name,omitempty"`
+	Color       *string  `json:"color,omitempty"`
+	Default     *bool    `json:"default,omitempty"`
+	Description *string  `json:"description,omitempty"`
+	Score       *float64 `json:"score,omitempty"`
+}
+
+func (l LabelResult) String() string {
+	return Stringify(l)
+}
+
+// Labels searches labels in the repository with ID repoID via various criteria.
+//
+// GitHub API docs: https://developer.github.com/v3/search/#search-labels
+func (s *SearchService) Labels(ctx context.Context, repoID int64, query string, opt *SearchOptions) (*LabelsSearchResult, *Response, error) {
+	result := new(LabelsSearchResult)
+	resp, err := s.search(ctx, "labels", &searchParameters{RepositoryID: &repoID, Query: query}, opt, result)
+	return result, resp, err
+}
+
+// Helper function that executes search queries against different
+// GitHub search types (repositories, commits, code, issues, users, labels)
+//
+// If searchParameters.Query includes multiple condition, it MUST NOT include "+" as condition separator.
+// For example, querying with "language:c++" and "leveldb", then searchParameters.Query should be "language:c++ leveldb" but not "language:c+++leveldb".
+func (s *SearchService) search(ctx context.Context, searchType string, parameters *searchParameters, opt *SearchOptions, result interface{}) (*Response, error) {
+	params, err := qs.Values(opt)
+	if err != nil {
+		return nil, err
+	}
+	if parameters.RepositoryID != nil {
+		params.Set("repository_id", strconv.FormatInt(*parameters.RepositoryID, 10))
+	}
+	params.Set("q", parameters.Query)
+	u := fmt.Sprintf("search/%s?%s", searchType, params.Encode())
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	switch {
+	case searchType == "commits":
+		// Accept header for search commits preview endpoint
+		// TODO: remove custom Accept header when this API fully launches.
+		req.Header.Set("Accept", mediaTypeCommitSearchPreview)
+	case searchType == "repositories":
+		// Accept header for search repositories based on topics preview endpoint
+		// TODO: remove custom Accept header when this API fully launches.
+		req.Header.Set("Accept", mediaTypeTopicsPreview)
+	case searchType == "labels":
+		// Accept header for search labels based on label description preview endpoint.
+		// TODO: remove custom Accept header when this API fully launches.
+		req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
+	case opt != nil && opt.TextMatch:
+		// Accept header defaults to "application/vnd.github.v3+json"
+		// We change it here to fetch back text-match metadata
+		req.Header.Set("Accept", "application/vnd.github.v3.text-match+json")
+	}
+
+	return s.client.Do(ctx, req, result)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/strings.go b/vendor/github.com/google/go-github/v24/github/strings.go
new file mode 100644
index 000000000..431e1cc6c
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/strings.go
@@ -0,0 +1,93 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+
+	"reflect"
+)
+
+var timestampType = reflect.TypeOf(Timestamp{})
+
+// Stringify attempts to create a reasonable string representation of types in
+// the GitHub library. It does things like resolve pointers to their values
+// and omits struct fields with nil values.
+func Stringify(message interface{}) string {
+	var buf bytes.Buffer
+	v := reflect.ValueOf(message)
+	stringifyValue(&buf, v)
+	return buf.String()
+}
+
+// stringifyValue was heavily inspired by the goprotobuf library.
+
+func stringifyValue(w io.Writer, val reflect.Value) {
+	if val.Kind() == reflect.Ptr && val.IsNil() {
+		w.Write([]byte("<nil>"))
+		return
+	}
+
+	v := reflect.Indirect(val)
+
+	switch v.Kind() {
+	case reflect.String:
+		fmt.Fprintf(w, `"%s"`, v)
+	case reflect.Slice:
+		w.Write([]byte{'['})
+		for i := 0; i < v.Len(); i++ {
+			if i > 0 {
+				w.Write([]byte{' '})
+			}
+
+			stringifyValue(w, v.Index(i))
+		}
+
+		w.Write([]byte{']'})
+		return
+	case reflect.Struct:
+		if v.Type().Name() != "" {
+			w.Write([]byte(v.Type().String()))
+		}
+
+		// special handling of Timestamp values
+		if v.Type() == timestampType {
+			fmt.Fprintf(w, "{%s}", v.Interface())
+			return
+		}
+
+		w.Write([]byte{'{'})
+
+		var sep bool
+		for i := 0; i < v.NumField(); i++ {
+			fv := v.Field(i)
+			if fv.Kind() == reflect.Ptr && fv.IsNil() {
+				continue
+			}
+			if fv.Kind() == reflect.Slice && fv.IsNil() {
+				continue
+			}
+
+			if sep {
+				w.Write([]byte(", "))
+			} else {
+				sep = true
+			}
+
+			w.Write([]byte(v.Type().Field(i).Name))
+			w.Write([]byte{':'})
+			stringifyValue(w, fv)
+		}
+
+		w.Write([]byte{'}'})
+	default:
+		if v.CanInterface() {
+			fmt.Fprint(w, v.Interface())
+		}
+	}
+}
diff --git a/vendor/github.com/google/go-github/v24/github/teams.go b/vendor/github.com/google/go-github/v24/github/teams.go
new file mode 100644
index 000000000..97d038d9b
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/teams.go
@@ -0,0 +1,457 @@
+// Copyright 2018 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"strings"
+	"time"
+)
+
+// TeamsService provides access to the team-related functions
+// in the GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/
+type TeamsService service
+
+// Team represents a team within a GitHub organization. Teams are used to
+// manage access to an organization's repositories.
+type Team struct {
+	ID          *int64  `json:"id,omitempty"`
+	Name        *string `json:"name,omitempty"`
+	Description *string `json:"description,omitempty"`
+	URL         *string `json:"url,omitempty"`
+	Slug        *string `json:"slug,omitempty"`
+
+	// Permission specifies the default permission for repositories owned by the team.
+	Permission *string `json:"permission,omitempty"`
+
+	// Privacy identifies the level of privacy this team should have.
+	// Possible values are:
+	//     secret - only visible to organization owners and members of this team
+	//     closed - visible to all members of this organization
+	// Default is "secret".
+	Privacy *string `json:"privacy,omitempty"`
+
+	MembersCount    *int          `json:"members_count,omitempty"`
+	ReposCount      *int          `json:"repos_count,omitempty"`
+	Organization    *Organization `json:"organization,omitempty"`
+	MembersURL      *string       `json:"members_url,omitempty"`
+	RepositoriesURL *string       `json:"repositories_url,omitempty"`
+	Parent          *Team         `json:"parent,omitempty"`
+
+	// LDAPDN is only available in GitHub Enterprise and when the team
+	// membership is synchronized with LDAP.
+	LDAPDN *string `json:"ldap_dn,omitempty"`
+}
+
+func (t Team) String() string {
+	return Stringify(t)
+}
+
+// Invitation represents a team member's invitation status.
+type Invitation struct {
+	ID    *int64  `json:"id,omitempty"`
+	Login *string `json:"login,omitempty"`
+	Email *string `json:"email,omitempty"`
+	// Role can be one of the values - 'direct_member', 'admin', 'billing_manager', 'hiring_manager', or 'reinstate'.
+	Role              *string    `json:"role,omitempty"`
+	CreatedAt         *time.Time `json:"created_at,omitempty"`
+	Inviter           *User      `json:"inviter,omitempty"`
+	TeamCount         *int       `json:"team_count,omitempty"`
+	InvitationTeamURL *string    `json:"invitation_team_url,omitempty"`
+}
+
+func (i Invitation) String() string {
+	return Stringify(i)
+}
+
+// ListTeams lists all of the teams for an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/#list-teams
+func (s *TeamsService) ListTeams(ctx context.Context, org string, opt *ListOptions) ([]*Team, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/teams", org)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
+	var teams []*Team
+	resp, err := s.client.Do(ctx, req, &teams)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return teams, resp, nil
+}
+
+// GetTeam fetches a team by ID.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/#get-team
+func (s *TeamsService) GetTeam(ctx context.Context, team int64) (*Team, *Response, error) {
+	u := fmt.Sprintf("teams/%v", team)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
+	t := new(Team)
+	resp, err := s.client.Do(ctx, req, t)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return t, resp, nil
+}
+
+// NewTeam represents a team to be created or modified.
+type NewTeam struct {
+	Name         string   `json:"name"` // Name of the team. (Required.)
+	Description  *string  `json:"description,omitempty"`
+	Maintainers  []string `json:"maintainers,omitempty"`
+	RepoNames    []string `json:"repo_names,omitempty"`
+	ParentTeamID *int64   `json:"parent_team_id,omitempty"`
+
+	// Deprecated: Permission is deprecated when creating or editing a team in an org
+	// using the new GitHub permission model. It no longer identifies the
+	// permission a team has on its repos, but only specifies the default
+	// permission a repo is initially added with. Avoid confusion by
+	// specifying a permission value when calling AddTeamRepo.
+	Permission *string `json:"permission,omitempty"`
+
+	// Privacy identifies the level of privacy this team should have.
+	// Possible values are:
+	//     secret - only visible to organization owners and members of this team
+	//     closed - visible to all members of this organization
+	// Default is "secret".
+	Privacy *string `json:"privacy,omitempty"`
+
+	// LDAPDN may be used in GitHub Enterprise when the team membership
+	// is synchronized with LDAP.
+	LDAPDN *string `json:"ldap_dn,omitempty"`
+}
+
+func (s NewTeam) String() string {
+	return Stringify(s)
+}
+
+// CreateTeam creates a new team within an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/#create-team
+func (s *TeamsService) CreateTeam(ctx context.Context, org string, team NewTeam) (*Team, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/teams", org)
+	req, err := s.client.NewRequest("POST", u, team)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
+	t := new(Team)
+	resp, err := s.client.Do(ctx, req, t)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return t, resp, nil
+}
+
+// EditTeam edits a team.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/#edit-team
+func (s *TeamsService) EditTeam(ctx context.Context, id int64, team NewTeam) (*Team, *Response, error) {
+	u := fmt.Sprintf("teams/%v", id)
+	req, err := s.client.NewRequest("PATCH", u, team)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
+	t := new(Team)
+	resp, err := s.client.Do(ctx, req, t)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return t, resp, nil
+}
+
+// DeleteTeam deletes a team.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/#delete-team
+func (s *TeamsService) DeleteTeam(ctx context.Context, team int64) (*Response, error) {
+	u := fmt.Sprintf("teams/%v", team)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// ListChildTeams lists child teams for a team.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/#list-child-teams
+func (s *TeamsService) ListChildTeams(ctx context.Context, teamID int64, opt *ListOptions) ([]*Team, *Response, error) {
+	u := fmt.Sprintf("teams/%v/teams", teamID)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
+	var teams []*Team
+	resp, err := s.client.Do(ctx, req, &teams)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return teams, resp, nil
+}
+
+// ListTeamRepos lists the repositories that the specified team has access to.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/#list-team-repos
+func (s *TeamsService) ListTeamRepos(ctx context.Context, team int64, opt *ListOptions) ([]*Repository, *Response, error) {
+	u := fmt.Sprintf("teams/%v/repos", team)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when topics API fully launches.
+	headers := []string{mediaTypeTopicsPreview, mediaTypeNestedTeamsPreview}
+	req.Header.Set("Accept", strings.Join(headers, ", "))
+
+	var repos []*Repository
+	resp, err := s.client.Do(ctx, req, &repos)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return repos, resp, nil
+}
+
+// IsTeamRepo checks if a team manages the specified repository. If the
+// repository is managed by team, a Repository is returned which includes the
+// permissions team has for that repo.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/#check-if-a-team-manages-a-repository
+func (s *TeamsService) IsTeamRepo(ctx context.Context, team int64, owner string, repo string) (*Repository, *Response, error) {
+	u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	headers := []string{mediaTypeOrgPermissionRepo, mediaTypeNestedTeamsPreview}
+	req.Header.Set("Accept", strings.Join(headers, ", "))
+
+	repository := new(Repository)
+	resp, err := s.client.Do(ctx, req, repository)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return repository, resp, nil
+}
+
+// TeamAddTeamRepoOptions specifies the optional parameters to the
+// TeamsService.AddTeamRepo method.
+type TeamAddTeamRepoOptions struct {
+	// Permission specifies the permission to grant the team on this repository.
+	// Possible values are:
+	//     pull - team members can pull, but not push to or administer this repository
+	//     push - team members can pull and push, but not administer this repository
+	//     admin - team members can pull, push and administer this repository
+	//
+	// If not specified, the team's permission attribute will be used.
+	Permission string `json:"permission,omitempty"`
+}
+
+// AddTeamRepo adds a repository to be managed by the specified team. The
+// specified repository must be owned by the organization to which the team
+// belongs, or a direct fork of a repository owned by the organization.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/#add-team-repo
+func (s *TeamsService) AddTeamRepo(ctx context.Context, team int64, owner string, repo string, opt *TeamAddTeamRepoOptions) (*Response, error) {
+	u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo)
+	req, err := s.client.NewRequest("PUT", u, opt)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// RemoveTeamRepo removes a repository from being managed by the specified
+// team. Note that this does not delete the repository, it just removes it
+// from the team.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/#remove-team-repo
+func (s *TeamsService) RemoveTeamRepo(ctx context.Context, team int64, owner string, repo string) (*Response, error) {
+	u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// ListUserTeams lists a user's teams
+// GitHub API docs: https://developer.github.com/v3/teams/#list-user-teams
+func (s *TeamsService) ListUserTeams(ctx context.Context, opt *ListOptions) ([]*Team, *Response, error) {
+	u := "user/teams"
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
+	var teams []*Team
+	resp, err := s.client.Do(ctx, req, &teams)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return teams, resp, nil
+}
+
+// ListTeamProjects lists the organization projects for a team.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/#list-team-projects
+func (s *TeamsService) ListTeamProjects(ctx context.Context, teamID int64) ([]*Project, *Response, error) {
+	u := fmt.Sprintf("teams/%v/projects", teamID)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	acceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	var projects []*Project
+	resp, err := s.client.Do(ctx, req, &projects)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return projects, resp, nil
+}
+
+// ReviewTeamProjects checks whether a team has read, write, or admin
+// permissions for an organization project.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/#review-a-team-project
+func (s *TeamsService) ReviewTeamProjects(ctx context.Context, teamID, projectID int64) (*Project, *Response, error) {
+	u := fmt.Sprintf("teams/%v/projects/%v", teamID, projectID)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	acceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	projects := &Project{}
+	resp, err := s.client.Do(ctx, req, &projects)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return projects, resp, nil
+}
+
+// TeamProjectOptions specifies the optional parameters to the
+// TeamsService.AddTeamProject method.
+type TeamProjectOptions struct {
+	// Permission specifies the permission to grant to the team for this project.
+	// Possible values are:
+	//     "read" - team members can read, but not write to or administer this project.
+	//     "write" - team members can read and write, but not administer this project.
+	//     "admin" - team members can read, write and administer this project.
+	//
+	Permission *string `json:"permission,omitempty"`
+}
+
+// AddTeamProject adds an organization project to a team. To add a project to a team or
+// update the team's permission on a project, the authenticated user must have admin
+// permissions for the project.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/#add-or-update-team-project
+func (s *TeamsService) AddTeamProject(ctx context.Context, teamID, projectID int64, opt *TeamProjectOptions) (*Response, error) {
+	u := fmt.Sprintf("teams/%v/projects/%v", teamID, projectID)
+	req, err := s.client.NewRequest("PUT", u, opt)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	acceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// RemoveTeamProject removes an organization project from a team. An organization owner or
+// a team maintainer can remove any project from the team. To remove a project from a team
+// as an organization member, the authenticated user must have "read" access to both the team
+// and project, or "admin" access to the team or project.
+// Note: This endpoint removes the project from the team, but does not delete it.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/#remove-team-project
+func (s *TeamsService) RemoveTeamProject(ctx context.Context, teamID int64, projectID int64) (*Response, error) {
+	u := fmt.Sprintf("teams/%v/projects/%v", teamID, projectID)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	acceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/teams_discussion_comments.go b/vendor/github.com/google/go-github/v24/github/teams_discussion_comments.go
new file mode 100644
index 000000000..a0206b9c9
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/teams_discussion_comments.go
@@ -0,0 +1,155 @@
+// Copyright 2018 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// DiscussionComment represents a GitHub dicussion in a team.
+type DiscussionComment struct {
+	Author        *User      `json:"author,omitempty"`
+	Body          *string    `json:"body,omitempty"`
+	BodyHTML      *string    `json:"body_html,omitempty"`
+	BodyVersion   *string    `json:"body_version,omitempty"`
+	CreatedAt     *Timestamp `json:"created_at,omitempty"`
+	LastEditedAt  *Timestamp `json:"last_edited_at,omitempty"`
+	DiscussionURL *string    `json:"discussion_url,omitempty"`
+	HTMLURL       *string    `json:"html_url,omitempty"`
+	NodeID        *string    `json:"node_id,omitempty"`
+	Number        *int       `json:"number,omitempty"`
+	UpdatedAt     *Timestamp `json:"updated_at,omitempty"`
+	URL           *string    `json:"url,omitempty"`
+	Reactions     *Reactions `json:"reactions,omitempty"`
+}
+
+func (c DiscussionComment) String() string {
+	return Stringify(c)
+}
+
+// DiscussionCommentListOptions specifies optional parameters to the
+// TeamServices.ListComments method.
+type DiscussionCommentListOptions struct {
+	// Sorts the discussion comments by the date they were created.
+	// Accepted values are asc and desc. Default is desc.
+	Direction string `url:"direction,omitempty"`
+}
+
+// ListComments lists all comments on a team discussion.
+// Authenticated user must grant read:discussion scope.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#list-comments
+func (s *TeamsService) ListComments(ctx context.Context, teamID int64, discussionNumber int, options *DiscussionCommentListOptions) ([]*DiscussionComment, *Response, error) {
+	u := fmt.Sprintf("teams/%v/discussions/%v/comments", teamID, discussionNumber)
+	u, err := addOptions(u, options)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview)
+
+	var comments []*DiscussionComment
+	resp, err := s.client.Do(ctx, req, &comments)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return comments, resp, nil
+}
+
+// GetComment gets a specific comment on a team discussion.
+// Authenticated user must grant read:discussion scope.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#get-a-single-comment
+func (s *TeamsService) GetComment(ctx context.Context, teamID int64, discussionNumber, commentNumber int) (*DiscussionComment, *Response, error) {
+	u := fmt.Sprintf("teams/%v/discussions/%v/comments/%v", teamID, discussionNumber, commentNumber)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview)
+
+	discussionComment := &DiscussionComment{}
+	resp, err := s.client.Do(ctx, req, discussionComment)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return discussionComment, resp, nil
+}
+
+// CreateComment creates a new discussion post on a team discussion.
+// Authenticated user must grant write:discussion scope.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#create-a-comment
+func (s *TeamsService) CreateComment(ctx context.Context, teamID int64, discsusionNumber int, comment DiscussionComment) (*DiscussionComment, *Response, error) {
+	u := fmt.Sprintf("teams/%v/discussions/%v/comments", teamID, discsusionNumber)
+	req, err := s.client.NewRequest("POST", u, comment)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview)
+
+	discussionComment := &DiscussionComment{}
+	resp, err := s.client.Do(ctx, req, discussionComment)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return discussionComment, resp, nil
+}
+
+// EditComment edits the body text of a discussion comment.
+// Authenticated user must grant write:discussion scope.
+// User is allowed to edit body of a comment only.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#edit-a-comment
+func (s *TeamsService) EditComment(ctx context.Context, teamID int64, discussionNumber, commentNumber int, comment DiscussionComment) (*DiscussionComment, *Response, error) {
+	u := fmt.Sprintf("teams/%v/discussions/%v/comments/%v", teamID, discussionNumber, commentNumber)
+	req, err := s.client.NewRequest("PATCH", u, comment)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview)
+
+	discussionComment := &DiscussionComment{}
+	resp, err := s.client.Do(ctx, req, discussionComment)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return discussionComment, resp, nil
+}
+
+// DeleteComment deletes a comment on a team discussion.
+// Authenticated user must grant write:discussion scope.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#delete-a-comment
+func (s *TeamsService) DeleteComment(ctx context.Context, teamID int64, discussionNumber, commentNumber int) (*Response, error) {
+	u := fmt.Sprintf("teams/%v/discussions/%v/comments/%v", teamID, discussionNumber, commentNumber)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/teams_discussions.go b/vendor/github.com/google/go-github/v24/github/teams_discussions.go
new file mode 100644
index 000000000..f491c9d1d
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/teams_discussions.go
@@ -0,0 +1,160 @@
+// Copyright 2018 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// TeamDiscussion represents a GitHub dicussion in a team.
+type TeamDiscussion struct {
+	Author        *User      `json:"author,omitempty"`
+	Body          *string    `json:"body,omitempty"`
+	BodyHTML      *string    `json:"body_html,omitempty"`
+	BodyVersion   *string    `json:"body_version,omitempty"`
+	CommentsCount *int       `json:"comments_count,omitempty"`
+	CommentsURL   *string    `json:"comments_url,omitempty"`
+	CreatedAt     *Timestamp `json:"created_at,omitempty"`
+	LastEditedAt  *Timestamp `json:"last_edited_at,omitempty"`
+	HTMLURL       *string    `json:"html_url,omitempty"`
+	NodeID        *string    `json:"node_id,omitempty"`
+	Number        *int       `json:"number,omitempty"`
+	Pinned        *bool      `json:"pinned,omitempty"`
+	Private       *bool      `json:"private,omitempty"`
+	TeamURL       *string    `json:"team_url,omitempty"`
+	Title         *string    `json:"title,omitempty"`
+	UpdatedAt     *Timestamp `json:"updated_at,omitempty"`
+	URL           *string    `json:"url,omitempty"`
+	Reactions     *Reactions `json:"reactions,omitempty"`
+}
+
+func (d TeamDiscussion) String() string {
+	return Stringify(d)
+}
+
+// DiscussionListOptions specifies optional parameters to the
+// TeamServices.ListDiscussions method.
+type DiscussionListOptions struct {
+	// Sorts the discussion by the date they were created.
+	// Accepted values are asc and desc. Default is desc.
+	Direction string `url:"direction,omitempty"`
+}
+
+// ListDiscussions lists all discussions on team's page.
+// Authenticated user must grant read:discussion scope.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/discussions/#list-discussions
+func (s *TeamsService) ListDiscussions(ctx context.Context, teamID int64, options *DiscussionListOptions) ([]*TeamDiscussion, *Response, error) {
+	u := fmt.Sprintf("teams/%v/discussions", teamID)
+	u, err := addOptions(u, options)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview)
+
+	var teamDiscussions []*TeamDiscussion
+	resp, err := s.client.Do(ctx, req, &teamDiscussions)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return teamDiscussions, resp, nil
+}
+
+// GetDiscussion gets a specific discussion on a team's page.
+// Authenticated user must grant read:discussion scope.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/discussions/#get-a-single-discussion
+func (s *TeamsService) GetDiscussion(ctx context.Context, teamID int64, discussionNumber int) (*TeamDiscussion, *Response, error) {
+	u := fmt.Sprintf("teams/%v/discussions/%v", teamID, discussionNumber)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview)
+
+	teamDiscussion := &TeamDiscussion{}
+	resp, err := s.client.Do(ctx, req, teamDiscussion)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return teamDiscussion, resp, nil
+}
+
+// CreateDiscussion creates a new discussion post on a team's page.
+// Authenticated user must grant write:discussion scope.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/discussions/#create-a-discussion
+func (s *TeamsService) CreateDiscussion(ctx context.Context, teamID int64, discussion TeamDiscussion) (*TeamDiscussion, *Response, error) {
+	u := fmt.Sprintf("teams/%v/discussions", teamID)
+	req, err := s.client.NewRequest("POST", u, discussion)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview)
+
+	teamDiscussion := &TeamDiscussion{}
+	resp, err := s.client.Do(ctx, req, teamDiscussion)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return teamDiscussion, resp, nil
+}
+
+// EditDiscussion edits the title and body text of a discussion post.
+// Authenticated user must grant write:discussion scope.
+// User is allowed to change Title and Body of a discussion only.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/discussions/#edit-a-discussion
+func (s *TeamsService) EditDiscussion(ctx context.Context, teamID int64, discussionNumber int, discussion TeamDiscussion) (*TeamDiscussion, *Response, error) {
+	u := fmt.Sprintf("teams/%v/discussions/%v", teamID, discussionNumber)
+	req, err := s.client.NewRequest("PATCH", u, discussion)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview)
+
+	teamDiscussion := &TeamDiscussion{}
+	resp, err := s.client.Do(ctx, req, teamDiscussion)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return teamDiscussion, resp, nil
+}
+
+// DeleteDiscussion deletes a discussion from team's page.
+// Authenticated user must grant write:discussion scope.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/discussions/#delete-a-discussion
+func (s *TeamsService) DeleteDiscussion(ctx context.Context, teamID int64, discussionNumber int) (*Response, error) {
+	u := fmt.Sprintf("teams/%v/discussions/%v", teamID, discussionNumber)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/teams_members.go b/vendor/github.com/google/go-github/v24/github/teams_members.go
new file mode 100644
index 000000000..d5cfa0dc7
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/teams_members.go
@@ -0,0 +1,174 @@
+// Copyright 2018 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// TeamListTeamMembersOptions specifies the optional parameters to the
+// TeamsService.ListTeamMembers method.
+type TeamListTeamMembersOptions struct {
+	// Role filters members returned by their role in the team. Possible
+	// values are "all", "member", "maintainer". Default is "all".
+	Role string `url:"role,omitempty"`
+
+	ListOptions
+}
+
+// ListTeamMembers lists all of the users who are members of the specified
+// team.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/members/#list-team-members
+func (s *TeamsService) ListTeamMembers(ctx context.Context, team int64, opt *TeamListTeamMembersOptions) ([]*User, *Response, error) {
+	u := fmt.Sprintf("teams/%v/members", team)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
+	var members []*User
+	resp, err := s.client.Do(ctx, req, &members)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return members, resp, nil
+}
+
+// IsTeamMember checks if a user is a member of the specified team.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/members/#get-team-member
+//
+// Deprecated: This API has been marked as deprecated in the Github API docs,
+// TeamsService.GetTeamMembership method should be used instead.
+func (s *TeamsService) IsTeamMember(ctx context.Context, team int64, user string) (bool, *Response, error) {
+	u := fmt.Sprintf("teams/%v/members/%v", team, user)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return false, nil, err
+	}
+
+	resp, err := s.client.Do(ctx, req, nil)
+	member, err := parseBoolResponse(err)
+	return member, resp, err
+}
+
+// GetTeamMembership returns the membership status for a user in a team.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/members/#get-team-membership
+func (s *TeamsService) GetTeamMembership(ctx context.Context, team int64, user string) (*Membership, *Response, error) {
+	u := fmt.Sprintf("teams/%v/memberships/%v", team, user)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
+	t := new(Membership)
+	resp, err := s.client.Do(ctx, req, t)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return t, resp, nil
+}
+
+// TeamAddTeamMembershipOptions specifies the optional
+// parameters to the TeamsService.AddTeamMembership method.
+type TeamAddTeamMembershipOptions struct {
+	// Role specifies the role the user should have in the team. Possible
+	// values are:
+	//     member - a normal member of the team
+	//     maintainer - a team maintainer. Able to add/remove other team
+	//                  members, promote other team members to team
+	//                  maintainer, and edit the team’s name and description
+	//
+	// Default value is "member".
+	Role string `json:"role,omitempty"`
+}
+
+// AddTeamMembership adds or invites a user to a team.
+//
+// In order to add a membership between a user and a team, the authenticated
+// user must have 'admin' permissions to the team or be an owner of the
+// organization that the team is associated with.
+//
+// If the user is already a part of the team's organization (meaning they're on
+// at least one other team in the organization), this endpoint will add the
+// user to the team.
+//
+// If the user is completely unaffiliated with the team's organization (meaning
+// they're on none of the organization's teams), this endpoint will send an
+// invitation to the user via email. This newly-created membership will be in
+// the "pending" state until the user accepts the invitation, at which point
+// the membership will transition to the "active" state and the user will be
+// added as a member of the team.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/members/#add-or-update-team-membership
+func (s *TeamsService) AddTeamMembership(ctx context.Context, team int64, user string, opt *TeamAddTeamMembershipOptions) (*Membership, *Response, error) {
+	u := fmt.Sprintf("teams/%v/memberships/%v", team, user)
+	req, err := s.client.NewRequest("PUT", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	t := new(Membership)
+	resp, err := s.client.Do(ctx, req, t)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return t, resp, nil
+}
+
+// RemoveTeamMembership removes a user from a team.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/members/#remove-team-membership
+func (s *TeamsService) RemoveTeamMembership(ctx context.Context, team int64, user string) (*Response, error) {
+	u := fmt.Sprintf("teams/%v/memberships/%v", team, user)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// ListPendingTeamInvitations get pending invitaion list in team.
+// Warning: The API may change without advance notice during the preview period.
+// Preview features are not supported for production use.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/members/#list-pending-team-invitations
+func (s *TeamsService) ListPendingTeamInvitations(ctx context.Context, team int64, opt *ListOptions) ([]*Invitation, *Response, error) {
+	u := fmt.Sprintf("teams/%v/invitations", team)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var pendingInvitations []*Invitation
+	resp, err := s.client.Do(ctx, req, &pendingInvitations)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return pendingInvitations, resp, nil
+}
diff --git a/vendor/github.com/google/go-github/v24/github/timestamp.go b/vendor/github.com/google/go-github/v24/github/timestamp.go
new file mode 100644
index 000000000..90929d575
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/timestamp.go
@@ -0,0 +1,41 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"strconv"
+	"time"
+)
+
+// Timestamp represents a time that can be unmarshalled from a JSON string
+// formatted as either an RFC3339 or Unix timestamp. This is necessary for some
+// fields since the GitHub API is inconsistent in how it represents times. All
+// exported methods of time.Time can be called on Timestamp.
+type Timestamp struct {
+	time.Time
+}
+
+func (t Timestamp) String() string {
+	return t.Time.String()
+}
+
+// UnmarshalJSON implements the json.Unmarshaler interface.
+// Time is expected in RFC3339 or Unix format.
+func (t *Timestamp) UnmarshalJSON(data []byte) (err error) {
+	str := string(data)
+	i, err := strconv.ParseInt(str, 10, 64)
+	if err == nil {
+		t.Time = time.Unix(i, 0)
+	} else {
+		t.Time, err = time.Parse(`"`+time.RFC3339+`"`, str)
+	}
+	return
+}
+
+// Equal reports whether t and u are equal based on time.Equal
+func (t Timestamp) Equal(u Timestamp) bool {
+	return t.Time.Equal(u.Time)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/users.go b/vendor/github.com/google/go-github/v24/github/users.go
new file mode 100644
index 000000000..87cfa7f84
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/users.go
@@ -0,0 +1,277 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// UsersService handles communication with the user related
+// methods of the GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/users/
+type UsersService service
+
+// User represents a GitHub user.
+type User struct {
+	Login                   *string    `json:"login,omitempty"`
+	ID                      *int64     `json:"id,omitempty"`
+	NodeID                  *string    `json:"node_id,omitempty"`
+	AvatarURL               *string    `json:"avatar_url,omitempty"`
+	HTMLURL                 *string    `json:"html_url,omitempty"`
+	GravatarID              *string    `json:"gravatar_id,omitempty"`
+	Name                    *string    `json:"name,omitempty"`
+	Company                 *string    `json:"company,omitempty"`
+	Blog                    *string    `json:"blog,omitempty"`
+	Location                *string    `json:"location,omitempty"`
+	Email                   *string    `json:"email,omitempty"`
+	Hireable                *bool      `json:"hireable,omitempty"`
+	Bio                     *string    `json:"bio,omitempty"`
+	PublicRepos             *int       `json:"public_repos,omitempty"`
+	PublicGists             *int       `json:"public_gists,omitempty"`
+	Followers               *int       `json:"followers,omitempty"`
+	Following               *int       `json:"following,omitempty"`
+	CreatedAt               *Timestamp `json:"created_at,omitempty"`
+	UpdatedAt               *Timestamp `json:"updated_at,omitempty"`
+	SuspendedAt             *Timestamp `json:"suspended_at,omitempty"`
+	Type                    *string    `json:"type,omitempty"`
+	SiteAdmin               *bool      `json:"site_admin,omitempty"`
+	TotalPrivateRepos       *int       `json:"total_private_repos,omitempty"`
+	OwnedPrivateRepos       *int       `json:"owned_private_repos,omitempty"`
+	PrivateGists            *int       `json:"private_gists,omitempty"`
+	DiskUsage               *int       `json:"disk_usage,omitempty"`
+	Collaborators           *int       `json:"collaborators,omitempty"`
+	TwoFactorAuthentication *bool      `json:"two_factor_authentication,omitempty"`
+	Plan                    *Plan      `json:"plan,omitempty"`
+
+	// API URLs
+	URL               *string `json:"url,omitempty"`
+	EventsURL         *string `json:"events_url,omitempty"`
+	FollowingURL      *string `json:"following_url,omitempty"`
+	FollowersURL      *string `json:"followers_url,omitempty"`
+	GistsURL          *string `json:"gists_url,omitempty"`
+	OrganizationsURL  *string `json:"organizations_url,omitempty"`
+	ReceivedEventsURL *string `json:"received_events_url,omitempty"`
+	ReposURL          *string `json:"repos_url,omitempty"`
+	StarredURL        *string `json:"starred_url,omitempty"`
+	SubscriptionsURL  *string `json:"subscriptions_url,omitempty"`
+
+	// TextMatches is only populated from search results that request text matches
+	// See: search.go and https://developer.github.com/v3/search/#text-match-metadata
+	TextMatches []TextMatch `json:"text_matches,omitempty"`
+
+	// Permissions identifies the permissions that a user has on a given
+	// repository. This is only populated when calling Repositories.ListCollaborators.
+	Permissions *map[string]bool `json:"permissions,omitempty"`
+}
+
+func (u User) String() string {
+	return Stringify(u)
+}
+
+// Get fetches a user. Passing the empty string will fetch the authenticated
+// user.
+//
+// GitHub API docs: https://developer.github.com/v3/users/#get-a-single-user
+// and: https://developer.github.com/v3/users/#get-the-authenticated-user
+func (s *UsersService) Get(ctx context.Context, user string) (*User, *Response, error) {
+	var u string
+	if user != "" {
+		u = fmt.Sprintf("users/%v", user)
+	} else {
+		u = "user"
+	}
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	uResp := new(User)
+	resp, err := s.client.Do(ctx, req, uResp)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return uResp, resp, nil
+}
+
+// GetByID fetches a user.
+//
+// Note: GetByID uses the undocumented GitHub API endpoint /user/:id.
+func (s *UsersService) GetByID(ctx context.Context, id int64) (*User, *Response, error) {
+	u := fmt.Sprintf("user/%d", id)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	user := new(User)
+	resp, err := s.client.Do(ctx, req, user)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return user, resp, nil
+}
+
+// Edit the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/users/#update-the-authenticated-user
+func (s *UsersService) Edit(ctx context.Context, user *User) (*User, *Response, error) {
+	u := "user"
+	req, err := s.client.NewRequest("PATCH", u, user)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	uResp := new(User)
+	resp, err := s.client.Do(ctx, req, uResp)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return uResp, resp, nil
+}
+
+// HovercardOptions specifies optional parameters to the UsersService.GetHovercard
+// method.
+type HovercardOptions struct {
+	// SubjectType specifies the additional information to be received about the hovercard.
+	// Possible values are: organization, repository, issue, pull_request. (Required when using subject_id.)
+	SubjectType string `url:"subject_type"`
+
+	// SubjectID specifies the ID for the SubjectType. (Required when using subject_type.)
+	SubjectID string `url:"subject_id"`
+}
+
+// Hovercard represents hovercard information about a user.
+type Hovercard struct {
+	Contexts []*UserContext `json:"contexts,omitempty"`
+}
+
+// UserContext represents the contextual information about user.
+type UserContext struct {
+	Message *string `json:"message,omitempty"`
+	Octicon *string `json:"octicon,omitempty"`
+}
+
+// GetHovercard fetches contextual information about user. It requires authentication
+// via Basic Auth or via OAuth with the repo scope.
+//
+// GitHub API docs: https://developer.github.com/v3/users/#get-contextual-information-about-a-user
+func (s *UsersService) GetHovercard(ctx context.Context, user string, opt *HovercardOptions) (*Hovercard, *Response, error) {
+	u := fmt.Sprintf("users/%v/hovercard", user)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeHovercardPreview)
+
+	hc := new(Hovercard)
+	resp, err := s.client.Do(ctx, req, hc)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return hc, resp, nil
+}
+
+// UserListOptions specifies optional parameters to the UsersService.ListAll
+// method.
+type UserListOptions struct {
+	// ID of the last user seen
+	Since int64 `url:"since,omitempty"`
+
+	// Note: Pagination is powered exclusively by the Since parameter,
+	// ListOptions.Page has no effect.
+	// ListOptions.PerPage controls an undocumented GitHub API parameter.
+	ListOptions
+}
+
+// ListAll lists all GitHub users.
+//
+// To paginate through all users, populate 'Since' with the ID of the last user.
+//
+// GitHub API docs: https://developer.github.com/v3/users/#get-all-users
+func (s *UsersService) ListAll(ctx context.Context, opt *UserListOptions) ([]*User, *Response, error) {
+	u, err := addOptions("users", opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var users []*User
+	resp, err := s.client.Do(ctx, req, &users)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return users, resp, nil
+}
+
+// ListInvitations lists all currently-open repository invitations for the
+// authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/invitations/#list-a-users-repository-invitations
+func (s *UsersService) ListInvitations(ctx context.Context, opt *ListOptions) ([]*RepositoryInvitation, *Response, error) {
+	u, err := addOptions("user/repository_invitations", opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	invites := []*RepositoryInvitation{}
+	resp, err := s.client.Do(ctx, req, &invites)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return invites, resp, nil
+}
+
+// AcceptInvitation accepts the currently-open repository invitation for the
+// authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/invitations/#accept-a-repository-invitation
+func (s *UsersService) AcceptInvitation(ctx context.Context, invitationID int64) (*Response, error) {
+	u := fmt.Sprintf("user/repository_invitations/%v", invitationID)
+	req, err := s.client.NewRequest("PATCH", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// DeclineInvitation declines the currently-open repository invitation for the
+// authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/invitations/#decline-a-repository-invitation
+func (s *UsersService) DeclineInvitation(ctx context.Context, invitationID int64) (*Response, error) {
+	u := fmt.Sprintf("user/repository_invitations/%v", invitationID)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/users_administration.go b/vendor/github.com/google/go-github/v24/github/users_administration.go
new file mode 100644
index 000000000..1c483a7b1
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/users_administration.go
@@ -0,0 +1,72 @@
+// Copyright 2014 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// PromoteSiteAdmin promotes a user to a site administrator of a GitHub Enterprise instance.
+//
+// GitHub API docs: https://developer.github.com/enterprise/v3/enterprise-admin/users/#promote-an-ordinary-user-to-a-site-administrator
+func (s *UsersService) PromoteSiteAdmin(ctx context.Context, user string) (*Response, error) {
+	u := fmt.Sprintf("users/%v/site_admin", user)
+
+	req, err := s.client.NewRequest("PUT", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// DemoteSiteAdmin demotes a user from site administrator of a GitHub Enterprise instance.
+//
+// GitHub API docs: https://developer.github.com/enterprise/v3/enterprise-admin/users/#demote-a-site-administrator-to-an-ordinary-user
+func (s *UsersService) DemoteSiteAdmin(ctx context.Context, user string) (*Response, error) {
+	u := fmt.Sprintf("users/%v/site_admin", user)
+
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// UserSuspendOptions represents the reason a user is being suspended.
+type UserSuspendOptions struct {
+	Reason *string `json:"reason,omitempty"`
+}
+
+// Suspend a user on a GitHub Enterprise instance.
+//
+// GitHub API docs: https://developer.github.com/enterprise/v3/enterprise-admin/users/#suspend-a-user
+func (s *UsersService) Suspend(ctx context.Context, user string, opt *UserSuspendOptions) (*Response, error) {
+	u := fmt.Sprintf("users/%v/suspended", user)
+
+	req, err := s.client.NewRequest("PUT", u, opt)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// Unsuspend a user on a GitHub Enterprise instance.
+//
+// GitHub API docs: https://developer.github.com/enterprise/v3/enterprise-admin/users/#unsuspend-a-user
+func (s *UsersService) Unsuspend(ctx context.Context, user string) (*Response, error) {
+	u := fmt.Sprintf("users/%v/suspended", user)
+
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/users_blocking.go b/vendor/github.com/google/go-github/v24/github/users_blocking.go
new file mode 100644
index 000000000..39e45601c
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/users_blocking.go
@@ -0,0 +1,91 @@
+// Copyright 2017 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// ListBlockedUsers lists all the blocked users by the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/users/blocking/#list-blocked-users
+func (s *UsersService) ListBlockedUsers(ctx context.Context, opt *ListOptions) ([]*User, *Response, error) {
+	u := "user/blocks"
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeBlockUsersPreview)
+
+	var blockedUsers []*User
+	resp, err := s.client.Do(ctx, req, &blockedUsers)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return blockedUsers, resp, nil
+}
+
+// IsBlocked reports whether specified user is blocked by the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/users/blocking/#check-whether-youve-blocked-a-user
+func (s *UsersService) IsBlocked(ctx context.Context, user string) (bool, *Response, error) {
+	u := fmt.Sprintf("user/blocks/%v", user)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return false, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeBlockUsersPreview)
+
+	resp, err := s.client.Do(ctx, req, nil)
+	isBlocked, err := parseBoolResponse(err)
+	return isBlocked, resp, err
+}
+
+// BlockUser blocks specified user for the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/users/blocking/#block-a-user
+func (s *UsersService) BlockUser(ctx context.Context, user string) (*Response, error) {
+	u := fmt.Sprintf("user/blocks/%v", user)
+
+	req, err := s.client.NewRequest("PUT", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeBlockUsersPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// UnblockUser unblocks specified user for the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/users/blocking/#unblock-a-user
+func (s *UsersService) UnblockUser(ctx context.Context, user string) (*Response, error) {
+	u := fmt.Sprintf("user/blocks/%v", user)
+
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeBlockUsersPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/users_emails.go b/vendor/github.com/google/go-github/v24/github/users_emails.go
new file mode 100644
index 000000000..0bbd4627e
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/users_emails.go
@@ -0,0 +1,71 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import "context"
+
+// UserEmail represents user's email address
+type UserEmail struct {
+	Email    *string `json:"email,omitempty"`
+	Primary  *bool   `json:"primary,omitempty"`
+	Verified *bool   `json:"verified,omitempty"`
+}
+
+// ListEmails lists all email addresses for the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/users/emails/#list-email-addresses-for-a-user
+func (s *UsersService) ListEmails(ctx context.Context, opt *ListOptions) ([]*UserEmail, *Response, error) {
+	u := "user/emails"
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var emails []*UserEmail
+	resp, err := s.client.Do(ctx, req, &emails)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return emails, resp, nil
+}
+
+// AddEmails adds email addresses of the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/users/emails/#add-email-addresses
+func (s *UsersService) AddEmails(ctx context.Context, emails []string) ([]*UserEmail, *Response, error) {
+	u := "user/emails"
+	req, err := s.client.NewRequest("POST", u, emails)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var e []*UserEmail
+	resp, err := s.client.Do(ctx, req, &e)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return e, resp, nil
+}
+
+// DeleteEmails deletes email addresses from authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/users/emails/#delete-email-addresses
+func (s *UsersService) DeleteEmails(ctx context.Context, emails []string) (*Response, error) {
+	u := "user/emails"
+	req, err := s.client.NewRequest("DELETE", u, emails)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/users_followers.go b/vendor/github.com/google/go-github/v24/github/users_followers.go
new file mode 100644
index 000000000..c2224096a
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/users_followers.go
@@ -0,0 +1,119 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// ListFollowers lists the followers for a user. Passing the empty string will
+// fetch followers for the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/users/followers/#list-followers-of-a-user
+func (s *UsersService) ListFollowers(ctx context.Context, user string, opt *ListOptions) ([]*User, *Response, error) {
+	var u string
+	if user != "" {
+		u = fmt.Sprintf("users/%v/followers", user)
+	} else {
+		u = "user/followers"
+	}
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var users []*User
+	resp, err := s.client.Do(ctx, req, &users)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return users, resp, nil
+}
+
+// ListFollowing lists the people that a user is following. Passing the empty
+// string will list people the authenticated user is following.
+//
+// GitHub API docs: https://developer.github.com/v3/users/followers/#list-users-followed-by-another-user
+func (s *UsersService) ListFollowing(ctx context.Context, user string, opt *ListOptions) ([]*User, *Response, error) {
+	var u string
+	if user != "" {
+		u = fmt.Sprintf("users/%v/following", user)
+	} else {
+		u = "user/following"
+	}
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var users []*User
+	resp, err := s.client.Do(ctx, req, &users)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return users, resp, nil
+}
+
+// IsFollowing checks if "user" is following "target". Passing the empty
+// string for "user" will check if the authenticated user is following "target".
+//
+// GitHub API docs: https://developer.github.com/v3/users/followers/#check-if-you-are-following-a-user
+func (s *UsersService) IsFollowing(ctx context.Context, user, target string) (bool, *Response, error) {
+	var u string
+	if user != "" {
+		u = fmt.Sprintf("users/%v/following/%v", user, target)
+	} else {
+		u = fmt.Sprintf("user/following/%v", target)
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return false, nil, err
+	}
+
+	resp, err := s.client.Do(ctx, req, nil)
+	following, err := parseBoolResponse(err)
+	return following, resp, err
+}
+
+// Follow will cause the authenticated user to follow the specified user.
+//
+// GitHub API docs: https://developer.github.com/v3/users/followers/#follow-a-user
+func (s *UsersService) Follow(ctx context.Context, user string) (*Response, error) {
+	u := fmt.Sprintf("user/following/%v", user)
+	req, err := s.client.NewRequest("PUT", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// Unfollow will cause the authenticated user to unfollow the specified user.
+//
+// GitHub API docs: https://developer.github.com/v3/users/followers/#unfollow-a-user
+func (s *UsersService) Unfollow(ctx context.Context, user string) (*Response, error) {
+	u := fmt.Sprintf("user/following/%v", user)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/users_gpg_keys.go b/vendor/github.com/google/go-github/v24/github/users_gpg_keys.go
new file mode 100644
index 000000000..07ed38dcb
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/users_gpg_keys.go
@@ -0,0 +1,128 @@
+// Copyright 2016 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// GPGKey represents a GitHub user's public GPG key used to verify GPG signed commits and tags.
+//
+// https://developer.github.com/changes/2016-04-04-git-signing-api-preview/
+type GPGKey struct {
+	ID                *int64     `json:"id,omitempty"`
+	PrimaryKeyID      *int64     `json:"primary_key_id,omitempty"`
+	KeyID             *string    `json:"key_id,omitempty"`
+	PublicKey         *string    `json:"public_key,omitempty"`
+	Emails            []GPGEmail `json:"emails,omitempty"`
+	Subkeys           []GPGKey   `json:"subkeys,omitempty"`
+	CanSign           *bool      `json:"can_sign,omitempty"`
+	CanEncryptComms   *bool      `json:"can_encrypt_comms,omitempty"`
+	CanEncryptStorage *bool      `json:"can_encrypt_storage,omitempty"`
+	CanCertify        *bool      `json:"can_certify,omitempty"`
+	CreatedAt         *time.Time `json:"created_at,omitempty"`
+	ExpiresAt         *time.Time `json:"expires_at,omitempty"`
+}
+
+// String stringifies a GPGKey.
+func (k GPGKey) String() string {
+	return Stringify(k)
+}
+
+// GPGEmail represents an email address associated to a GPG key.
+type GPGEmail struct {
+	Email    *string `json:"email,omitempty"`
+	Verified *bool   `json:"verified,omitempty"`
+}
+
+// ListGPGKeys lists the public GPG keys for a user. Passing the empty
+// string will fetch keys for the authenticated user. It requires authentication
+// via Basic Auth or via OAuth with at least read:gpg_key scope.
+//
+// GitHub API docs: https://developer.github.com/v3/users/gpg_keys/#list-gpg-keys-for-a-user
+func (s *UsersService) ListGPGKeys(ctx context.Context, user string, opt *ListOptions) ([]*GPGKey, *Response, error) {
+	var u string
+	if user != "" {
+		u = fmt.Sprintf("users/%v/gpg_keys", user)
+	} else {
+		u = "user/gpg_keys"
+	}
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var keys []*GPGKey
+	resp, err := s.client.Do(ctx, req, &keys)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return keys, resp, nil
+}
+
+// GetGPGKey gets extended details for a single GPG key. It requires authentication
+// via Basic Auth or via OAuth with at least read:gpg_key scope.
+//
+// GitHub API docs: https://developer.github.com/v3/users/gpg_keys/#get-a-single-gpg-key
+func (s *UsersService) GetGPGKey(ctx context.Context, id int64) (*GPGKey, *Response, error) {
+	u := fmt.Sprintf("user/gpg_keys/%v", id)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	key := &GPGKey{}
+	resp, err := s.client.Do(ctx, req, key)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return key, resp, nil
+}
+
+// CreateGPGKey creates a GPG key. It requires authenticatation via Basic Auth
+// or OAuth with at least write:gpg_key scope.
+//
+// GitHub API docs: https://developer.github.com/v3/users/gpg_keys/#create-a-gpg-key
+func (s *UsersService) CreateGPGKey(ctx context.Context, armoredPublicKey string) (*GPGKey, *Response, error) {
+	gpgKey := &struct {
+		ArmoredPublicKey string `json:"armored_public_key"`
+	}{ArmoredPublicKey: armoredPublicKey}
+	req, err := s.client.NewRequest("POST", "user/gpg_keys", gpgKey)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	key := &GPGKey{}
+	resp, err := s.client.Do(ctx, req, key)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return key, resp, nil
+}
+
+// DeleteGPGKey deletes a GPG key. It requires authentication via Basic Auth or
+// via OAuth with at least admin:gpg_key scope.
+//
+// GitHub API docs: https://developer.github.com/v3/users/gpg_keys/#delete-a-gpg-key
+func (s *UsersService) DeleteGPGKey(ctx context.Context, id int64) (*Response, error) {
+	u := fmt.Sprintf("user/gpg_keys/%v", id)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/users_keys.go b/vendor/github.com/google/go-github/v24/github/users_keys.go
new file mode 100644
index 000000000..ddc832a1e
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/users_keys.go
@@ -0,0 +1,108 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// Key represents a public SSH key used to authenticate a user or deploy script.
+type Key struct {
+	ID       *int64  `json:"id,omitempty"`
+	Key      *string `json:"key,omitempty"`
+	URL      *string `json:"url,omitempty"`
+	Title    *string `json:"title,omitempty"`
+	ReadOnly *bool   `json:"read_only,omitempty"`
+}
+
+func (k Key) String() string {
+	return Stringify(k)
+}
+
+// ListKeys lists the verified public keys for a user. Passing the empty
+// string will fetch keys for the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/users/keys/#list-public-keys-for-a-user
+func (s *UsersService) ListKeys(ctx context.Context, user string, opt *ListOptions) ([]*Key, *Response, error) {
+	var u string
+	if user != "" {
+		u = fmt.Sprintf("users/%v/keys", user)
+	} else {
+		u = "user/keys"
+	}
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var keys []*Key
+	resp, err := s.client.Do(ctx, req, &keys)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return keys, resp, nil
+}
+
+// GetKey fetches a single public key.
+//
+// GitHub API docs: https://developer.github.com/v3/users/keys/#get-a-single-public-key
+func (s *UsersService) GetKey(ctx context.Context, id int64) (*Key, *Response, error) {
+	u := fmt.Sprintf("user/keys/%v", id)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	key := new(Key)
+	resp, err := s.client.Do(ctx, req, key)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return key, resp, nil
+}
+
+// CreateKey adds a public key for the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/users/keys/#create-a-public-key
+func (s *UsersService) CreateKey(ctx context.Context, key *Key) (*Key, *Response, error) {
+	u := "user/keys"
+
+	req, err := s.client.NewRequest("POST", u, key)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	k := new(Key)
+	resp, err := s.client.Do(ctx, req, k)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return k, resp, nil
+}
+
+// DeleteKey deletes a public key.
+//
+// GitHub API docs: https://developer.github.com/v3/users/keys/#delete-a-public-key
+func (s *UsersService) DeleteKey(ctx context.Context, id int64) (*Response, error) {
+	u := fmt.Sprintf("user/keys/%v", id)
+
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/vendor/github.com/google/go-github/v24/github/with_appengine.go b/vendor/github.com/google/go-github/v24/github/with_appengine.go
new file mode 100644
index 000000000..59ce26b2e
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/with_appengine.go
@@ -0,0 +1,20 @@
+// Copyright 2017 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build appengine
+
+// This file provides glue for making github work on App Engine.
+
+package github
+
+import (
+	"context"
+	"net/http"
+)
+
+func withContext(ctx context.Context, req *http.Request) *http.Request {
+	// No-op because App Engine adds context to a request differently.
+	return req
+}
diff --git a/vendor/github.com/google/go-github/v24/github/without_appengine.go b/vendor/github.com/google/go-github/v24/github/without_appengine.go
new file mode 100644
index 000000000..6f8fdac56
--- /dev/null
+++ b/vendor/github.com/google/go-github/v24/github/without_appengine.go
@@ -0,0 +1,19 @@
+// Copyright 2017 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !appengine
+
+// This file provides glue for making github work without App Engine.
+
+package github
+
+import (
+	"context"
+	"net/http"
+)
+
+func withContext(ctx context.Context, req *http.Request) *http.Request {
+	return req.WithContext(ctx)
+}
diff --git a/vendor/github.com/google/go-querystring/LICENSE b/vendor/github.com/google/go-querystring/LICENSE
new file mode 100644
index 000000000..ae121a1e4
--- /dev/null
+++ b/vendor/github.com/google/go-querystring/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2013 Google. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/google/go-querystring/query/encode.go b/vendor/github.com/google/go-querystring/query/encode.go
new file mode 100644
index 000000000..37080b19b
--- /dev/null
+++ b/vendor/github.com/google/go-querystring/query/encode.go
@@ -0,0 +1,320 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package query implements encoding of structs into URL query parameters.
+//
+// As a simple example:
+//
+// 	type Options struct {
+// 		Query   string `url:"q"`
+// 		ShowAll bool   `url:"all"`
+// 		Page    int    `url:"page"`
+// 	}
+//
+// 	opt := Options{ "foo", true, 2 }
+// 	v, _ := query.Values(opt)
+// 	fmt.Print(v.Encode()) // will output: "q=foo&all=true&page=2"
+//
+// The exact mapping between Go values and url.Values is described in the
+// documentation for the Values() function.
+package query
+
+import (
+	"bytes"
+	"fmt"
+	"net/url"
+	"reflect"
+	"strconv"
+	"strings"
+	"time"
+)
+
+var timeType = reflect.TypeOf(time.Time{})
+
+var encoderType = reflect.TypeOf(new(Encoder)).Elem()
+
+// Encoder is an interface implemented by any type that wishes to encode
+// itself into URL values in a non-standard way.
+type Encoder interface {
+	EncodeValues(key string, v *url.Values) error
+}
+
+// Values returns the url.Values encoding of v.
+//
+// Values expects to be passed a struct, and traverses it recursively using the
+// following encoding rules.
+//
+// Each exported struct field is encoded as a URL parameter unless
+//
+//	- the field's tag is "-", or
+//	- the field is empty and its tag specifies the "omitempty" option
+//
+// The empty values are false, 0, any nil pointer or interface value, any array
+// slice, map, or string of length zero, and any time.Time that returns true
+// for IsZero().
+//
+// The URL parameter name defaults to the struct field name but can be
+// specified in the struct field's tag value.  The "url" key in the struct
+// field's tag value is the key name, followed by an optional comma and
+// options.  For example:
+//
+// 	// Field is ignored by this package.
+// 	Field int `url:"-"`
+//
+// 	// Field appears as URL parameter "myName".
+// 	Field int `url:"myName"`
+//
+// 	// Field appears as URL parameter "myName" and the field is omitted if
+// 	// its value is empty
+// 	Field int `url:"myName,omitempty"`
+//
+// 	// Field appears as URL parameter "Field" (the default), but the field
+// 	// is skipped if empty.  Note the leading comma.
+// 	Field int `url:",omitempty"`
+//
+// For encoding individual field values, the following type-dependent rules
+// apply:
+//
+// Boolean values default to encoding as the strings "true" or "false".
+// Including the "int" option signals that the field should be encoded as the
+// strings "1" or "0".
+//
+// time.Time values default to encoding as RFC3339 timestamps.  Including the
+// "unix" option signals that the field should be encoded as a Unix time (see
+// time.Unix())
+//
+// Slice and Array values default to encoding as multiple URL values of the
+// same name.  Including the "comma" option signals that the field should be
+// encoded as a single comma-delimited value.  Including the "space" option
+// similarly encodes the value as a single space-delimited string. Including
+// the "semicolon" option will encode the value as a semicolon-delimited string.
+// Including the "brackets" option signals that the multiple URL values should
+// have "[]" appended to the value name. "numbered" will append a number to
+// the end of each incidence of the value name, example:
+// name0=value0&name1=value1, etc.
+//
+// Anonymous struct fields are usually encoded as if their inner exported
+// fields were fields in the outer struct, subject to the standard Go
+// visibility rules.  An anonymous struct field with a name given in its URL
+// tag is treated as having that name, rather than being anonymous.
+//
+// Non-nil pointer values are encoded as the value pointed to.
+//
+// Nested structs are encoded including parent fields in value names for
+// scoping. e.g:
+//
+// 	"user[name]=acme&user[addr][postcode]=1234&user[addr][city]=SFO"
+//
+// All other values are encoded using their default string representation.
+//
+// Multiple fields that encode to the same URL parameter name will be included
+// as multiple URL values of the same name.
+func Values(v interface{}) (url.Values, error) {
+	values := make(url.Values)
+	val := reflect.ValueOf(v)
+	for val.Kind() == reflect.Ptr {
+		if val.IsNil() {
+			return values, nil
+		}
+		val = val.Elem()
+	}
+
+	if v == nil {
+		return values, nil
+	}
+
+	if val.Kind() != reflect.Struct {
+		return nil, fmt.Errorf("query: Values() expects struct input. Got %v", val.Kind())
+	}
+
+	err := reflectValue(values, val, "")
+	return values, err
+}
+
+// reflectValue populates the values parameter from the struct fields in val.
+// Embedded structs are followed recursively (using the rules defined in the
+// Values function documentation) breadth-first.
+func reflectValue(values url.Values, val reflect.Value, scope string) error {
+	var embedded []reflect.Value
+
+	typ := val.Type()
+	for i := 0; i < typ.NumField(); i++ {
+		sf := typ.Field(i)
+		if sf.PkgPath != "" && !sf.Anonymous { // unexported
+			continue
+		}
+
+		sv := val.Field(i)
+		tag := sf.Tag.Get("url")
+		if tag == "-" {
+			continue
+		}
+		name, opts := parseTag(tag)
+		if name == "" {
+			if sf.Anonymous && sv.Kind() == reflect.Struct {
+				// save embedded struct for later processing
+				embedded = append(embedded, sv)
+				continue
+			}
+
+			name = sf.Name
+		}
+
+		if scope != "" {
+			name = scope + "[" + name + "]"
+		}
+
+		if opts.Contains("omitempty") && isEmptyValue(sv) {
+			continue
+		}
+
+		if sv.Type().Implements(encoderType) {
+			if !reflect.Indirect(sv).IsValid() {
+				sv = reflect.New(sv.Type().Elem())
+			}
+
+			m := sv.Interface().(Encoder)
+			if err := m.EncodeValues(name, &values); err != nil {
+				return err
+			}
+			continue
+		}
+
+		if sv.Kind() == reflect.Slice || sv.Kind() == reflect.Array {
+			var del byte
+			if opts.Contains("comma") {
+				del = ','
+			} else if opts.Contains("space") {
+				del = ' '
+			} else if opts.Contains("semicolon") {
+				del = ';'
+			} else if opts.Contains("brackets") {
+				name = name + "[]"
+			}
+
+			if del != 0 {
+				s := new(bytes.Buffer)
+				first := true
+				for i := 0; i < sv.Len(); i++ {
+					if first {
+						first = false
+					} else {
+						s.WriteByte(del)
+					}
+					s.WriteString(valueString(sv.Index(i), opts))
+				}
+				values.Add(name, s.String())
+			} else {
+				for i := 0; i < sv.Len(); i++ {
+					k := name
+					if opts.Contains("numbered") {
+						k = fmt.Sprintf("%s%d", name, i)
+					}
+					values.Add(k, valueString(sv.Index(i), opts))
+				}
+			}
+			continue
+		}
+
+		for sv.Kind() == reflect.Ptr {
+			if sv.IsNil() {
+				break
+			}
+			sv = sv.Elem()
+		}
+
+		if sv.Type() == timeType {
+			values.Add(name, valueString(sv, opts))
+			continue
+		}
+
+		if sv.Kind() == reflect.Struct {
+			reflectValue(values, sv, name)
+			continue
+		}
+
+		values.Add(name, valueString(sv, opts))
+	}
+
+	for _, f := range embedded {
+		if err := reflectValue(values, f, scope); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+// valueString returns the string representation of a value.
+func valueString(v reflect.Value, opts tagOptions) string {
+	for v.Kind() == reflect.Ptr {
+		if v.IsNil() {
+			return ""
+		}
+		v = v.Elem()
+	}
+
+	if v.Kind() == reflect.Bool && opts.Contains("int") {
+		if v.Bool() {
+			return "1"
+		}
+		return "0"
+	}
+
+	if v.Type() == timeType {
+		t := v.Interface().(time.Time)
+		if opts.Contains("unix") {
+			return strconv.FormatInt(t.Unix(), 10)
+		}
+		return t.Format(time.RFC3339)
+	}
+
+	return fmt.Sprint(v.Interface())
+}
+
+// isEmptyValue checks if a value should be considered empty for the purposes
+// of omitting fields with the "omitempty" option.
+func isEmptyValue(v reflect.Value) bool {
+	switch v.Kind() {
+	case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
+		return v.Len() == 0
+	case reflect.Bool:
+		return !v.Bool()
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return v.Int() == 0
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return v.Uint() == 0
+	case reflect.Float32, reflect.Float64:
+		return v.Float() == 0
+	case reflect.Interface, reflect.Ptr:
+		return v.IsNil()
+	}
+
+	if v.Type() == timeType {
+		return v.Interface().(time.Time).IsZero()
+	}
+
+	return false
+}
+
+// tagOptions is the string following a comma in a struct field's "url" tag, or
+// the empty string. It does not include the leading comma.
+type tagOptions []string
+
+// parseTag splits a struct field's url tag into its name and comma-separated
+// options.
+func parseTag(tag string) (string, tagOptions) {
+	s := strings.Split(tag, ",")
+	return s[0], s[1:]
+}
+
+// Contains checks whether the tagOptions contains the specified option.
+func (o tagOptions) Contains(option string) bool {
+	for _, s := range o {
+		if s == option {
+			return true
+		}
+	}
+	return false
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 41edf76a9..370cfece9 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -167,6 +167,10 @@ github.com/gogits/cron
 github.com/golang/protobuf/proto
 # github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db
 github.com/golang/snappy
+# github.com/google/go-github/v24 v24.0.1
+github.com/google/go-github/v24/github
+# github.com/google/go-querystring v1.0.0
+github.com/google/go-querystring/query
 # github.com/gorilla/context v1.1.1
 github.com/gorilla/context
 # github.com/gorilla/mux v1.6.2
@@ -356,8 +360,8 @@ golang.org/x/crypto/ssh/agent
 golang.org/x/net/html/charset
 golang.org/x/net/html
 golang.org/x/net/html/atom
-golang.org/x/net/context
 golang.org/x/net/context/ctxhttp
+golang.org/x/net/context
 # golang.org/x/oauth2 v0.0.0-20181101160152-c453e0c75759
 golang.org/x/oauth2
 golang.org/x/oauth2/internal