1
0
mirror of https://github.com/StackExchange/dnscontrol.git synced 2024-05-11 05:55:12 +00:00

update some dependencies (#208)

* update some dependencies

* some more

* add these

* remove things?

* regen
This commit is contained in:
Craig Peterson
2017-09-18 15:35:10 -04:00
committed by GitHub
parent ae14b0e790
commit e4ad084494
141 changed files with 3816 additions and 15671 deletions

View File

@@ -46,10 +46,10 @@ func (e *Event) ParsePayload() (payload interface{}, err error) {
payload = &ForkEvent{}
case "GollumEvent":
payload = &GollumEvent{}
case "IntegrationInstallationEvent":
payload = &IntegrationInstallationEvent{}
case "IntegrationInstallationRepositoriesEvent":
payload = &IntegrationInstallationRepositoriesEvent{}
case "InstallationEvent":
payload = &InstallationEvent{}
case "InstallationRepositoriesEvent":
payload = &InstallationRepositoriesEvent{}
case "IssueCommentEvent":
payload = &IssueCommentEvent{}
case "IssuesEvent":
@@ -64,6 +64,8 @@ func (e *Event) ParsePayload() (payload interface{}, err error) {
payload = &MilestoneEvent{}
case "OrganizationEvent":
payload = &OrganizationEvent{}
case "OrgBlockEvent":
payload = &OrgBlockEvent{}
case "PageBuildEvent":
payload = &PageBuildEvent{}
case "PingEvent":
@@ -90,6 +92,8 @@ func (e *Event) ParsePayload() (payload interface{}, err error) {
payload = &RepositoryEvent{}
case "StatusEvent":
payload = &StatusEvent{}
case "TeamEvent":
payload = &TeamEvent{}
case "TeamAddEvent":
payload = &TeamAddEvent{}
case "WatchEvent":

View File

@@ -7,17 +7,17 @@ package github
import "context"
// IntegrationsService provides access to the installation related functions
// AppsService provides access to the installation related functions
// in the GitHub API.
//
// GitHub API docs: https://developer.github.com/v3/integrations/
type IntegrationsService service
// GitHub API docs: https://developer.github.com/v3/apps/
type AppsService service
// ListInstallations lists the installations that the current integration has.
// ListInstallations lists the installations that the current GitHub App has.
//
// GitHub API docs: https://developer.github.com/v3/integrations/#find-installations
func (s *IntegrationsService) ListInstallations(ctx context.Context, opt *ListOptions) ([]*Installation, *Response, error) {
u, err := addOptions("integration/installations", opt)
// 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
}

View File

@@ -7,7 +7,7 @@ package github
import "context"
// Installation represents a GitHub integration installation.
// Installation represents a GitHub Apps installation.
type Installation struct {
ID *int `json:"id,omitempty"`
Account *User `json:"account,omitempty"`
@@ -20,10 +20,10 @@ func (i Installation) String() string {
return Stringify(i)
}
// ListRepos lists the repositories that the current installation has access to.
// ListRepos lists the repositories that are accessible to the authenticated installation.
//
// GitHub API docs: https://developer.github.com/v3/integrations/installations/#list-repositories
func (s *IntegrationsService) ListRepos(ctx context.Context, opt *ListOptions) ([]*Repository, *Response, error) {
// 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

View File

@@ -63,7 +63,7 @@ type Authorization struct {
App *AuthorizationApp `json:"app,omitempty"`
Note *string `json:"note,omitempty"`
NoteURL *string `json:"note_url,omitempty"`
UpdateAt *Timestamp `json:"updated_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
Fingerprint *string `json:"fingerprint,omitempty"`
@@ -343,8 +343,13 @@ func (s *AuthorizationsService) Revoke(ctx context.Context, clientID string, tok
// 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) ([]*Grant, *Response, error) {
req, err := s.client.NewRequest("GET", "applications/grants", nil)
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
}

View File

@@ -63,19 +63,38 @@ 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. To receive the higher rate limit when making calls
that are not issued on behalf of a user, use the
UnauthenticatedRateLimitedTransport.
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 Rate method on a client returns the rate limit information based on the most
recent API call. This is updated on every call, but may be out of date if it's
been some time since the last API call and other clients have made subsequent
requests since then. You can always call RateLimits() directly to get the most
up-to-date rate limit data for the client.
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:
@@ -154,7 +173,7 @@ github.Response struct.
if resp.NextPage == 0 {
break
}
opt.ListOptions.Page = resp.NextPage
opt.Page = resp.NextPage
}
Google App Engine
@@ -164,7 +183,7 @@ the "context" import and still relies on "golang.org/x/net/context".
As a result, if you wish to continue to use "go-github" on App Engine Classic,
you will need to rewrite all the "context" imports using the following command:
gofmt -w -r '"context" -> "golang.org/x/net/context"' *.go
gofmt -w -r '"context" -> "golang.org/x/net/context"' *.go
See "with_appengine.go" for more details.

View File

@@ -165,28 +165,49 @@ type ProjectColumnChange struct {
} `json:"name,omitempty"`
}
// IntegrationInstallationEvent is triggered when an integration is created or deleted.
// The Webhook event name is "integration_installation".
// 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/early-access/integrations/webhooks/#integrationinstallationevent
type IntegrationInstallationEvent struct {
// The action that was performed. Possible values for an "integration_installation"
// event are: "created", "deleted".
// 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"`
Sender *User `json:"sender,omitempty"`
Installation *Installation `json:"installation,omitempty"`
}
// IntegrationInstallationRepositoriesEvent is triggered when an integration repository
// is added or removed. The Webhook event name is "integration_installation_repositories".
// 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/early-access/integrations/webhooks/#integrationinstallationrepositoriesevent
type IntegrationInstallationRepositoriesEvent struct {
// The action that was performed. Possible values for an "integration_installation_repositories"
// event are: "added", "removed".
// 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"`
}
@@ -323,6 +344,22 @@ type OrganizationEvent struct {
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".
@@ -637,6 +674,25 @@ type StatusEvent struct {
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".
//

View File

@@ -1,299 +0,0 @@
// 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"
"time"
)
const (
fileSuffix = "-accessors.go"
)
var (
verbose = flag.Bool("v", false, "Print verbose log messages")
sourceTmpl = template.Must(template.New("source").Parse(source))
// blacklist lists which "struct.method" combos to not generate.
blacklist = map[string]bool{
"RepositoryContent.GetContent": true,
"Client.GetBaseURL": true,
"Client.GetUploadURL": true,
"ErrorResponse.GetResponse": true,
"RateLimitError.GetResponse": true,
"AbuseRateLimitError.GetResponse": 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: time.Now().Year(),
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
}
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]
if key := fmt.Sprintf("%v.Get%v", ts.Name, fieldName); blacklist[key] {
logf("Method %v 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) *getter {
return &getter{
sortVal: strings.ToLower(receiverType) + "." + strings.ToLower(fieldName),
ReceiverVar: strings.ToLower(receiverType[:1]),
ReceiverType: receiverType,
FieldName: fieldName,
FieldType: fieldType,
ZeroValue: zeroValue,
}
}
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"))
}
func (t *templateData) addIdent(x *ast.Ident, receiverType, fieldName string) {
var zeroValue string
switch x.String() {
case "int":
zeroValue = "0"
case "string":
zeroValue = `""`
case "bool":
zeroValue = "false"
case "Timestamp":
zeroValue = "Timestamp{}"
default: // other structs handled by their receivers directly.
return
}
t.Getters = append(t.Getters, newGetter(receiverType, fieldName, x.String(), zeroValue))
}
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))
}
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))
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
}
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}}
// 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}}
`

View File

@@ -241,8 +241,13 @@ func (s *GistsService) Edit(ctx context.Context, id string, gist *Gist) (*Gist,
// 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) ([]*GistCommit, *Response, error) {
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

View File

@@ -7,6 +7,8 @@ package github
import (
"context"
"encoding/json"
"errors"
"fmt"
"strings"
)
@@ -45,7 +47,11 @@ type updateRefRequest struct {
Force *bool `json:"force"`
}
// GetRef fetches the Reference object for a given Git ref.
// 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) {
@@ -58,13 +64,61 @@ func (s *GitService) GetRef(ctx context.Context, owner string, repo string, ref
r := new(Reference)
resp, err := s.client.Do(ctx, req, r)
if err != nil {
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, 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 {

View File

@@ -30,6 +30,7 @@ type TreeEntry struct {
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 {

View File

@@ -20,6 +20,14 @@ func (a *AbuseRateLimitError) GetRetryAfter() time.Duration {
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
}
// GetVerifiablePasswordAuthentication returns the VerifiablePasswordAuthentication field if it's non-nil, zero value otherwise.
func (a *APIMeta) GetVerifiablePasswordAuthentication() bool {
if a == nil || a.VerifiablePasswordAuthentication == nil {
@@ -92,12 +100,12 @@ func (a *Authorization) GetTokenLastEight() string {
return *a.TokenLastEight
}
// GetUpdateAt returns the UpdateAt field if it's non-nil, zero value otherwise.
func (a *Authorization) GetUpdateAt() Timestamp {
if a == nil || a.UpdateAt == nil {
// 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.UpdateAt
return *a.UpdatedAt
}
// GetURL returns the URL field if it's non-nil, zero value otherwise.
@@ -252,6 +260,38 @@ func (b *Branch) GetProtected() bool {
return *b.Protected
}
// 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 {
@@ -556,6 +596,38 @@ func (c *CommitsComparison) GetBehindBy() int {
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
}
// 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 {
@@ -572,6 +644,14 @@ func (c *CommitsComparison) GetTotalCommits() int {
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 {
@@ -612,6 +692,22 @@ func (c *CommitStats) GetTotal() int {
return *c.Total
}
// 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 {
@@ -1917,7 +2013,7 @@ func (i *Installation) GetRepositoriesURL() string {
}
// GetAction returns the Action field if it's non-nil, zero value otherwise.
func (i *IntegrationInstallationEvent) GetAction() string {
func (i *InstallationEvent) GetAction() string {
if i == nil || i.Action == nil {
return ""
}
@@ -1925,13 +2021,21 @@ func (i *IntegrationInstallationEvent) GetAction() string {
}
// GetAction returns the Action field if it's non-nil, zero value otherwise.
func (i *IntegrationInstallationRepositoriesEvent) GetAction() string {
func (i *InstallationRepositoriesEvent) GetAction() string {
if i == nil || i.Action == nil {
return ""
}
return *i.Action
}
// 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
}
// 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 {
@@ -2548,6 +2652,38 @@ func (m *MembershipEvent) GetScope() string {
return *m.Scope
}
// 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 {
@@ -3108,6 +3244,14 @@ func (o *OrganizationEvent) GetAction() string {
return *o.Action
}
// 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
}
// GetAction returns the Action field if it's non-nil, zero value otherwise.
func (p *Page) GetAction() string {
if p == nil || p.Action == nil {
@@ -3372,6 +3516,14 @@ func (p *Project) GetURL() string {
return *p.URL
}
// GetColumnID returns the ColumnID field if it's non-nil, zero value otherwise.
func (p *ProjectCard) GetColumnID() int {
if p == nil || p.ColumnID == nil {
return 0
}
return *p.ColumnID
}
// GetColumnURL returns the ColumnURL field if it's non-nil, zero value otherwise.
func (p *ProjectCard) GetColumnURL() string {
if p == nil || p.ColumnURL == nil {
@@ -3420,6 +3572,14 @@ func (p *ProjectCard) GetUpdatedAt() 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 {
@@ -3612,6 +3772,14 @@ func (p *PullRequest) GetMergeable() bool {
return *p.Mergeable
}
// 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 {
@@ -3996,6 +4164,14 @@ func (p *PullRequestReviewRequest) GetBody() string {
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 {
@@ -4004,6 +4180,14 @@ func (p *PullRequestReviewRequest) GetEvent() string {
return *p.Event
}
// 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
}
// GetBase returns the Base field if it's non-nil, zero value otherwise.
func (p *pullRequestUpdate) GetBase() string {
if p == nil || p.Base == nil {
@@ -6292,6 +6476,14 @@ func (t *Team) GetURL() string {
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
}
// GetDescription returns the Description field if it's non-nil, zero value otherwise.
func (t *TeamLDAPMapping) GetDescription() string {
if t == nil || t.Description == nil {
@@ -6620,6 +6812,14 @@ func (t *TreeEntry) GetType() string {
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
}
// GetForce returns the Force field if it's non-nil, zero value otherwise.
func (u *updateRefRequest) GetForce() bool {
if u == nil || u.Force == nil {

View File

@@ -27,7 +27,7 @@ import (
)
const (
libraryVersion = "6"
libraryVersion = "11"
defaultBaseURL = "https://api.github.com/"
uploadBaseURL = "https://uploads.github.com/"
userAgent = "go-github/" + libraryVersion
@@ -67,10 +67,6 @@ const (
// https://developer.github.com/changes/2016-05-12-reactions-api-preview/
mediaTypeReactionsPreview = "application/vnd.github.squirrel-girl-preview"
// https://developer.github.com/changes/2016-04-01-squash-api-preview/
// https://developer.github.com/changes/2016-09-26-pull-request-merge-api-update/
mediaTypeSquashPreview = "application/vnd.github.polaris-preview+json"
// https://developer.github.com/changes/2016-04-04-git-signing-api-preview/
mediaTypeGitSigningPreview = "application/vnd.github.cryptographer-preview+json"
@@ -92,11 +88,20 @@ const (
// https://developer.github.com/changes/2017-01-05-commit-search-api/
mediaTypeCommitSearchPreview = "application/vnd.github.cloak-preview+json"
// https://developer.github.com/changes/2016-12-14-reviews-api/
mediaTypePullRequestReviewsPreview = "application/vnd.github.black-cat-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-07-26-team-review-request-thor-preview/
mediaTypeTeamReviewPreview = "application/vnd.github.thor-preview+json"
)
// A Client manages communication with the GitHub API.
@@ -123,11 +128,11 @@ type Client struct {
// Services used for talking to different parts of the GitHub API.
Activity *ActivityService
Admin *AdminService
Apps *AppsService
Authorizations *AuthorizationsService
Gists *GistsService
Git *GitService
Gitignores *GitignoresService
Integrations *IntegrationsService
Issues *IssuesService
Organizations *OrganizationsService
Projects *ProjectsService
@@ -212,11 +217,11 @@ func NewClient(httpClient *http.Client) *Client {
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.Gists = (*GistsService)(&c.common)
c.Git = (*GitService)(&c.common)
c.Gitignores = (*GitignoresService)(&c.common)
c.Integrations = (*IntegrationsService)(&c.common)
c.Issues = (*IssuesService)(&c.common)
c.Licenses = (*LicensesService)(&c.common)
c.Migrations = (*MigrationService)(&c.common)
@@ -236,13 +241,14 @@ func NewClient(httpClient *http.Client) *Client {
// 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) {
rel, err := url.Parse(urlStr)
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
}
u := c.BaseURL.ResolveReference(rel)
var buf io.ReadWriter
if body != nil {
buf = new(bytes.Buffer)
@@ -271,12 +277,14 @@ func (c *Client) NewRequest(method, urlStr string, body interface{}) (*http.Requ
// 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) {
rel, err := url.Parse(urlStr)
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
}
u := c.UploadURL.ResolveReference(rel)
req, err := http.NewRequest("POST", u.String(), reader)
if err != nil {
return nil, err
@@ -312,6 +320,7 @@ type Response struct {
}
// 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()
@@ -390,13 +399,16 @@ func parseRate(r *http.Response) Rate {
// 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) {
ctx, req = withContext(ctx, req)
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 nil, err
return &Response{
Response: err.Response,
Rate: err.Rate,
}, err
}
resp, err := c.client.Do(req)
@@ -457,7 +469,7 @@ func (c *Client) Do(ctx context.Context, req *http.Request, v interface{}) (*Res
// 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) error {
func (c *Client) checkRateLimitBeforeDo(req *http.Request, rateLimitCategory rateLimitCategory) *RateLimitError {
c.rateMu.Lock()
rate := c.rateLimits[rateLimitCategory]
c.rateMu.Unlock()
@@ -524,9 +536,9 @@ type RateLimitError struct {
}
func (r *RateLimitError) Error() string {
return fmt.Sprintf("%v %v: %d %v; rate reset in %v",
return fmt.Sprintf("%v %v: %d %v %v",
r.Response.Request.Method, sanitizeURL(r.Response.Request.URL),
r.Response.StatusCode, r.Message, r.Rate.Reset.Time.Sub(time.Now()))
r.Response.StatusCode, r.Message, formatRateReset(r.Rate.Reset.Time.Sub(time.Now())))
}
// AcceptedError occurs when GitHub returns 202 Accepted response with an
@@ -874,6 +886,31 @@ func cloneRequest(r *http.Request) *http.Request {
return r2
}
// 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 }

View File

@@ -44,7 +44,7 @@ type IssueEvent struct {
// Someone unspecified @mentioned the Actor [sic] in an issue comment body.
//
// assigned, unassigned
// The Actor assigned the issue to or removed the assignment from the Assignee.
// 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.

View File

@@ -19,7 +19,7 @@ type Label struct {
}
func (l Label) String() string {
return fmt.Sprint(*l.Name)
return Stringify(l)
}
// ListLabels lists all labels for a repository.

View File

@@ -33,42 +33,46 @@ const (
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{
"commit_comment": "CommitCommentEvent",
"create": "CreateEvent",
"delete": "DeleteEvent",
"deployment": "DeploymentEvent",
"deployment_status": "DeploymentStatusEvent",
"fork": "ForkEvent",
"gollum": "GollumEvent",
"integration_installation": "IntegrationInstallationEvent",
"integration_installation_repositories": "IntegrationInstallationRepositoriesEvent",
"issue_comment": "IssueCommentEvent",
"issues": "IssuesEvent",
"label": "LabelEvent",
"member": "MemberEvent",
"membership": "MembershipEvent",
"milestone": "MilestoneEvent",
"organization": "OrganizationEvent",
"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",
"release": "ReleaseEvent",
"status": "StatusEvent",
"team_add": "TeamAddEvent",
"watch": "WatchEvent",
"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",
"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",
"release": "ReleaseEvent",
"status": "StatusEvent",
"team": "TeamEvent",
"team_add": "TeamAddEvent",
"watch": "WatchEvent",
}
)
@@ -159,10 +163,19 @@ func validateSignature(signature string, payload, secretKey []byte) error {
}
// 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

View File

@@ -83,6 +83,61 @@ func (c *Client) ListEmojis(ctx context.Context) (map[string]string, *Response,
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

View File

@@ -154,6 +154,25 @@ func (s *OrganizationsService) Get(ctx context.Context, org string) (*Organizati
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 int) (*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

View File

@@ -223,6 +223,9 @@ func (s *OrganizationsService) ListTeamRepos(ctx context.Context, team int, opt
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 {

View File

@@ -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)
}

View File

@@ -259,14 +259,19 @@ func (s *ProjectsService) MoveProjectColumn(ctx context.Context, columnID int, o
// ProjectCard represents a card in a column of a GitHub Project.
//
// GitHub API docs: https://developer.github.com/v3/repos/projects/
// 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 *int `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"`
// The following fields are only populated by Webhook events.
ColumnID *int `json:"column_id,omitempty"`
}
// ListProjectCards lists the cards in a column of a GitHub Project.
@@ -324,10 +329,10 @@ func (s *ProjectsService) GetProjectCard(ctx context.Context, columnID int) (*Pr
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 or Pull Request to associate with this card.
// The ID (not Number) of the Issue to associate with this card.
// Note and ContentID are mutually exclusive.
ContentID int `json:"content_id,omitempty"`
// The type of content to associate with this card. Possible values are: "Issue", "PullRequest".
// The type of content to associate with this card. Possible values are: "Issue".
ContentType string `json:"content_type,omitempty"`
}

View File

@@ -33,6 +33,7 @@ type PullRequest struct {
Merged *bool `json:"merged,omitempty"`
Mergeable *bool `json:"mergeable,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"`
@@ -253,6 +254,9 @@ func (s *PullRequestsService) ListCommits(ctx context.Context, owner string, rep
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeGitSigningPreview)
var commits []*RepositoryCommit
resp, err := s.client.Do(ctx, req, &commits)
if err != nil {
@@ -342,9 +346,6 @@ func (s *PullRequestsService) Merge(ctx context.Context, owner string, repo stri
return nil, nil, err
}
// TODO: This header will be unnecessary when the API is no longer in preview.
req.Header.Set("Accept", mediaTypeSquashPreview)
mergeResult := new(PullRequestMergeResult)
resp, err := s.client.Do(ctx, req, mergeResult)
if err != nil {

View File

@@ -10,24 +10,30 @@ import (
"fmt"
)
// RequestReviewers creates a review request for the provided GitHub users for the specified pull request.
// 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, logins []string) (*PullRequest, *Response, error) {
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)
reviewers := struct {
Reviewers []string `json:"reviewers,omitempty"`
}{
Reviewers: logins,
}
req, err := s.client.NewRequest("POST", u, &reviewers)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches
req.Header.Set("Accept", mediaTypePullRequestReviewsPreview)
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeTeamReviewPreview)
r := new(PullRequest)
resp, err := s.client.Do(ctx, req, r)
@@ -38,47 +44,45 @@ func (s *PullRequestsService) RequestReviewers(ctx context.Context, owner, repo
return r, resp, nil
}
// ListReviewers lists users whose reviews have been requested on the specified pull request.
// 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) ([]*User, *Response, error) {
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
}
// TODO: remove custom Accept header when this API fully launches
req.Header.Set("Accept", mediaTypePullRequestReviewsPreview)
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeTeamReviewPreview)
var users []*User
resp, err := s.client.Do(ctx, req, &users)
reviewers := new(Reviewers)
resp, err := s.client.Do(ctx, req, reviewers)
if err != nil {
return nil, resp, err
}
return users, resp, nil
return reviewers, resp, nil
}
// RemoveReviewers removes the review request for the provided GitHub users for the specified pull request.
// 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, logins []string) (*Response, error) {
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)
reviewers := struct {
Reviewers []string `json:"reviewers,omitempty"`
}{
Reviewers: logins,
}
req, err := s.client.NewRequest("DELETE", u, &reviewers)
if err != nil {
return nil, err
}
// TODO: remove custom Accept header when this API fully launches
req.Header.Set("Accept", mediaTypePullRequestReviewsPreview)
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeTeamReviewPreview)
return s.client.Do(ctx, req, reviewers)
}

View File

@@ -40,6 +40,7 @@ func (c DraftReviewComment) String() string {
// 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"`
@@ -65,17 +66,18 @@ func (r PullRequestReviewDismissalRequest) String() string {
// 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) ([]*PullRequestReview, *Response, error) {
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
}
// TODO: remove custom Accept header when this API fully launches
req.Header.Set("Accept", mediaTypePullRequestReviewsPreview)
var reviews []*PullRequestReview
resp, err := s.client.Do(ctx, req, &reviews)
if err != nil {
@@ -100,9 +102,6 @@ func (s *PullRequestsService) GetReview(ctx context.Context, owner, repo string,
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches
req.Header.Set("Accept", mediaTypePullRequestReviewsPreview)
review := new(PullRequestReview)
resp, err := s.client.Do(ctx, req, review)
if err != nil {
@@ -127,9 +126,6 @@ func (s *PullRequestsService) DeletePendingReview(ctx context.Context, owner, re
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches
req.Header.Set("Accept", mediaTypePullRequestReviewsPreview)
review := new(PullRequestReview)
resp, err := s.client.Do(ctx, req, review)
if err != nil {
@@ -145,18 +141,19 @@ func (s *PullRequestsService) DeletePendingReview(ctx context.Context, owner, re
// 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-reviews-comments
func (s *PullRequestsService) ListReviewComments(ctx context.Context, owner, repo string, number, reviewID int) ([]*PullRequestComment, *Response, error) {
// 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, reviewID int, 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
}
// TODO: remove custom Accept header when this API fully launches
req.Header.Set("Accept", mediaTypePullRequestReviewsPreview)
var comments []*PullRequestComment
resp, err := s.client.Do(ctx, req, &comments)
if err != nil {
@@ -181,9 +178,6 @@ func (s *PullRequestsService) CreateReview(ctx context.Context, owner, repo stri
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches
req.Header.Set("Accept", mediaTypePullRequestReviewsPreview)
r := new(PullRequestReview)
resp, err := s.client.Do(ctx, req, r)
if err != nil {
@@ -208,9 +202,6 @@ func (s *PullRequestsService) SubmitReview(ctx context.Context, owner, repo stri
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches
req.Header.Set("Accept", mediaTypePullRequestReviewsPreview)
r := new(PullRequestReview)
resp, err := s.client.Do(ctx, req, r)
if err != nil {
@@ -235,9 +226,6 @@ func (s *PullRequestsService) DismissReview(ctx context.Context, owner, repo str
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches
req.Header.Set("Accept", mediaTypePullRequestReviewsPreview)
r := new(PullRequestReview)
resp, err := s.client.Do(ctx, req, r)
if err != nil {

View File

@@ -7,6 +7,7 @@ package github
import (
"context"
"encoding/json"
"fmt"
"strings"
)
@@ -25,6 +26,7 @@ type Repository struct {
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"`
@@ -53,6 +55,7 @@ type Repository struct {
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"`
// Only provided when using RepositoriesService.Get while in preview
License *License `json:"license,omitempty"`
@@ -173,8 +176,9 @@ func (s *RepositoriesService) List(ctx context.Context, user string, opt *Reposi
return nil, nil, err
}
// TODO: remove custom Accept header when license support fully launches
req.Header.Set("Accept", mediaTypeLicensesPreview)
// TODO: remove custom Accept headers when APIs fully launch.
acceptHeaders := []string{mediaTypeLicensesPreview, mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview}
req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
var repos []*Repository
resp, err := s.client.Do(ctx, req, &repos)
@@ -210,8 +214,9 @@ func (s *RepositoriesService) ListByOrg(ctx context.Context, org string, opt *Re
return nil, nil, err
}
// TODO: remove custom Accept header when license support fully launches
req.Header.Set("Accept", mediaTypeLicensesPreview)
// TODO: remove custom Accept headers when APIs fully launch.
acceptHeaders := []string{mediaTypeLicensesPreview, mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview}
req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
var repos []*Repository
resp, err := s.client.Do(ctx, req, &repos)
@@ -293,7 +298,7 @@ func (s *RepositoriesService) Get(ctx context.Context, owner, repo string) (*Rep
// TODO: remove custom Accept header when the license support fully launches
// https://developer.github.com/v3/licenses/#get-a-repositorys-license
acceptHeaders := []string{mediaTypeLicensesPreview, mediaTypeSquashPreview}
acceptHeaders := []string{mediaTypeLicensesPreview, mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview}
req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
repository := new(Repository)
@@ -305,6 +310,28 @@ func (s *RepositoriesService) Get(ctx context.Context, owner, repo string) (*Rep
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.
@@ -338,9 +365,6 @@ func (s *RepositoriesService) Edit(ctx context.Context, owner, repo string, repo
return nil, nil, err
}
// TODO: Remove this preview header after API is fully vetted.
req.Header.Set("Accept", mediaTypeSquashPreview)
r := new(Repository)
resp, err := s.client.Do(ctx, req, r)
if err != nil {
@@ -509,22 +533,22 @@ type Branch struct {
// Protection represents a repository branch's protection.
type Protection struct {
RequiredStatusChecks *RequiredStatusChecks `json:"required_status_checks"`
RequiredPullRequestReviews *RequiredPullRequestReviews `json:"required_pull_request_reviews"`
Restrictions *BranchRestrictions `json:"restrictions"`
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 *RequiredPullRequestReviews `json:"required_pull_request_reviews"`
Restrictions *BranchRestrictionsRequest `json:"restrictions"`
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 {
// Enforce required status checks for repository administrators. (Required.)
IncludeAdmins bool `json:"include_admins"`
// 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
@@ -532,10 +556,61 @@ type RequiredStatusChecks struct {
Contexts []string `json:"contexts"`
}
// RequiredPullRequestReviews represents the protection configuration for pull requests.
type RequiredPullRequestReviews struct {
// Enforce pull request reviews for repository administrators. (Required.)
IncludeAdmins bool `json:"include_admins"`
// 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"`
}
// 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. Can be nil to disable the restrictions.
DismissalRestrictionsRequest *DismissalRestrictionsRequest `json:"dismissal_restrictions"`
// Specifies if approved reviews can be dismissed automatically, when a new commit is pushed. (Required)
DismissStaleReviews bool `json:"dismiss_stale_reviews"`
}
// MarshalJSON implements the json.Marshaler interface.
// Converts nil value of PullRequestReviewsEnforcementRequest.DismissalRestrictionsRequest to empty array
func (req PullRequestReviewsEnforcementRequest) MarshalJSON() ([]byte, error) {
if req.DismissalRestrictionsRequest == nil {
newReq := struct {
R []interface{} `json:"dismissal_restrictions"`
D bool `json:"dismiss_stale_reviews"`
}{
R: []interface{}{},
D: req.DismissStaleReviews,
}
return json.Marshal(newReq)
}
newReq := struct {
R *DismissalRestrictionsRequest `json:"dismissal_restrictions"`
D bool `json:"dismiss_stale_reviews"`
}{
R: req.DismissalRestrictionsRequest,
D: req.DismissStaleReviews,
}
return json.Marshal(newReq)
}
// 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"`
}
// 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
@@ -558,6 +633,25 @@ type BranchRestrictionsRequest struct {
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.
type DismissalRestrictionsRequest struct {
// The list of user logins who can dismiss pull request reviews. (Required; use []string{} instead of nil for empty list.)
Users []string `json:"users"`
// The list of team slugs which can dismiss pull request reviews. (Required; use []string{} instead of nil for empty list.)
Teams []string `json:"teams"`
}
// ListBranches lists branches for the specified repository.
//
// GitHub API docs: https://developer.github.com/v3/repos/#list-branches
@@ -728,3 +822,202 @@ func (s *RepositoriesService) License(ctx context.Context, owner, repo string) (
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", mediaTypeProtectedBranchesPreview)
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", mediaTypeProtectedBranchesPreview)
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", mediaTypeProtectedBranchesPreview)
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", mediaTypeProtectedBranchesPreview)
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", mediaTypeProtectedBranchesPreview)
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", mediaTypeProtectedBranchesPreview)
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", mediaTypeProtectedBranchesPreview)
return s.client.Do(ctx, req, nil)
}
// Topics represents a collection of repository topics.
type Topics struct {
Names []string `json:"names,omitempty"`
}
// 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) (*Topics, *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(Topics)
resp, err := s.client.Do(ctx, req, topics)
if err != nil {
return nil, resp, err
}
return topics, 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 *Topics) (*Topics, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/topics", owner, repo)
req, err := s.client.NewRequest("PUT", u, topics)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeTopicsPreview)
t := new(Topics)
resp, err := s.client.Do(ctx, req, t)
if err != nil {
return nil, resp, err
}
return t, resp, nil
}

View File

@@ -10,10 +10,26 @@ import (
"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
func (s *RepositoriesService) ListCollaborators(ctx context.Context, owner, repo string, opt *ListOptions) ([]*User, *Response, error) {
// 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 {
@@ -91,7 +107,8 @@ type RepositoryAddCollaboratorOptions struct {
Permission string `json:"permission,omitempty"`
}
// AddCollaborator adds the specified GitHub user as collaborator to the given repo.
// 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) {

View File

@@ -79,6 +79,12 @@ type CommitsComparison struct {
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 {
@@ -121,6 +127,9 @@ func (s *RepositoriesService) ListCommits(ctx context.Context, owner, repo strin
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeGitSigningPreview)
var commits []*RepositoryCommit
resp, err := s.client.Do(ctx, req, &commits)
if err != nil {

View File

@@ -0,0 +1,57 @@
// 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"`
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
}

View File

@@ -164,7 +164,7 @@ func (s *RepositoriesService) GetContents(ctx context.Context, owner, repo, path
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)
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
@@ -248,7 +248,7 @@ func (s *RepositoriesService) GetArchiveLink(ctx context.Context, owner, repo st
}
var resp *http.Response
// Use http.DefaultTransport if no custom Transport is configured
ctx, req = withContext(ctx, req)
req = withContext(ctx, req)
if s.client.client.Transport == nil {
resp, err = http.DefaultTransport.RoundTrip(req)
} else {

View File

@@ -23,7 +23,7 @@ type Deployment struct {
Description *string `json:"description,omitempty"`
Creator *User `json:"creator,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"pushed_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
StatusesURL *string `json:"statuses_url,omitempty"`
RepositoryURL *string `json:"repository_url,omitempty"`
}
@@ -137,7 +137,7 @@ type DeploymentStatus struct {
Description *string `json:"description,omitempty"`
TargetURL *string `json:"target_url,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"pushed_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
DeploymentURL *string `json:"deployment_url,omitempty"`
RepositoryURL *string `json:"repository_url,omitempty"`
}

View File

@@ -35,6 +35,9 @@ func (s *RepositoriesService) ListForks(ctx context.Context, owner, repo string,
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 {

View File

@@ -90,5 +90,9 @@ func (s *RepositoriesService) UpdateInvitation(ctx context.Context, owner, repo
invite := &RepositoryInvitation{}
resp, err := s.client.Do(ctx, req, invite)
return invite, resp, err
if err != nil {
return nil, resp, err
}
return invite, resp, nil
}

View File

@@ -61,8 +61,13 @@ func (s *RepositoriesService) GetPagesInfo(ctx context.Context, owner, repo stri
// 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) ([]*PagesBuild, *Response, error) {
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

View File

@@ -244,7 +244,7 @@ func (s *RepositoriesService) DownloadReleaseAsset(ctx context.Context, owner, r
}
defer func() { s.client.client.CheckRedirect = saveRedirect }()
ctx, req = withContext(ctx, req)
req = withContext(ctx, req)
resp, err := s.client.client.Do(req)
if err != nil {
if !strings.Contains(err.Error(), "disable redirect") {

View File

@@ -15,6 +15,14 @@ import (
// 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
@@ -188,6 +196,10 @@ func (s *SearchService) search(ctx context.Context, searchType string, query str
// 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 opt != nil && opt.TextMatch:
// Accept header defaults to "application/vnd.github.v3+json"
// We change it here to fetch back text-match metadata

View File

@@ -172,8 +172,13 @@ func (s *UsersService) ListAll(ctx context.Context, opt *UserListOptions) ([]*Us
// authenticated user.
//
// GitHub API docs: https://developer.github.com/v3/repos/invitations/#list-a-users-repository-invitations
func (s *UsersService) ListInvitations(ctx context.Context) ([]*RepositoryInvitation, *Response, error) {
req, err := s.client.NewRequest("GET", "user/repository_invitations", nil)
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
}

View File

@@ -43,7 +43,7 @@ type GPGEmail struct {
// 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

View File

@@ -17,10 +17,9 @@ package github
import (
"context"
"net/http"
"google.golang.org/appengine"
)
func withContext(ctx context.Context, req *http.Request) (context.Context, *http.Request) {
return appengine.WithContext(ctx, req), req
func withContext(ctx context.Context, req *http.Request) *http.Request {
// No-op because App Engine adds context to a request differently.
return req
}

View File

@@ -14,6 +14,6 @@ import (
"net/http"
)
func withContext(ctx context.Context, req *http.Request) (context.Context, *http.Request) {
return ctx, req.WithContext(ctx)
func withContext(ctx context.Context, req *http.Request) *http.Request {
return req.WithContext(ctx)
}