Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Jasder 2020-08-03 15:13:48 +08:00
commit 001c8df0be
143 changed files with 9598 additions and 2705 deletions

View File

@ -47,6 +47,8 @@ If pre-built frontend files are present it is possible to only build the backend
TAGS="bindata" make backend
Parallelism is not supported for these targets, so please don't include `-j <num>`.
More info: https://docs.gitea.io/en-us/install-from-source/
## Using

4
go.mod
View File

@ -50,7 +50,7 @@ require (
github.com/gogs/chardet v0.0.0-20191104214054-4b6791f73a28
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
github.com/golang/protobuf v1.4.1 // indirect
github.com/google/go-github/v24 v24.0.1
github.com/google/go-github/v32 v32.1.0
github.com/google/uuid v1.1.1
github.com/gorilla/context v1.1.1
github.com/hashicorp/go-retryablehttp v0.6.6 // indirect
@ -100,7 +100,7 @@ require (
github.com/urfave/cli v1.20.0
github.com/xanzy/go-gitlab v0.31.0
github.com/yohcop/openid-go v1.0.0
github.com/yuin/goldmark v1.1.32
github.com/yuin/goldmark v1.2.1
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691
github.com/yuin/goldmark-meta v0.0.0-20191126180153-f0638e958b60
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9

10
go.sum
View File

@ -349,10 +349,8 @@ github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
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-github/v32 v32.1.0 h1:GWkQOdXqviCPx7Q7Fj+KyPoGm4SwHRh8rheoPhd27II=
github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@ -715,6 +713,8 @@ github.com/yuin/goldmark v1.1.25 h1:isv+Q6HQAmmL2Ofcmg8QauBmDPlUUnSoNhEcC940Rds=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32 h1:5tjfNdR2ki3yYQ842+eX2sQHeiwpKJ0RnHO4IYOc4V8=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1 h1:ruQGxdhGHe7FWOJPT0mKs5+pD2Xs1Bm/kdGlHO04FmM=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691 h1:VWSxtAiQNh3zgHJpdpkpVYjTPqRE3P6UZCOPa1nRDio=
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691/go.mod h1:YLF3kDffRfUH/bTxOxHhV6lxwIB3Vfj91rEwNMS9MXo=
github.com/yuin/goldmark-meta v0.0.0-20191126180153-f0638e958b60 h1:gZucqLjL1eDzVWrXj4uiWeMbAopJlBR2mKQAsTGdPwo=
@ -734,7 +734,6 @@ go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@ -809,7 +808,6 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/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-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=

View File

@ -220,6 +220,8 @@ var migrations = []Migration{
NewMigration("Ensure Repository.IsArchived is not null", setIsArchivedToFalse),
// v143 -> v144
NewMigration("recalculate Stars number for all user", recalculateStars),
// v144 -> v145
NewMigration("update Matrix Webhook http method to 'PUT'", updateMatrixWebhookHTTPMethod),
}
// GetCurrentDBVersion returns the current db version

25
models/migrations/v144.go Normal file
View File

@ -0,0 +1,25 @@
// Copyright 2020 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/log"
"xorm.io/builder"
"xorm.io/xorm"
)
func updateMatrixWebhookHTTPMethod(x *xorm.Engine) error {
var matrixHookTaskType = 9 // value comes from the models package
type Webhook struct {
HTTPMethod string
}
cond := builder.Eq{"hook_task_type": matrixHookTaskType}.And(builder.Neq{"http_method": "PUT"})
count, err := x.Where(cond).Cols("http_method").Update(&Webhook{HTTPMethod: "PUT"})
if err == nil {
log.Debug("Updated %d Matrix webhooks with http_method 'PUT'", count)
}
return err
}

View File

@ -27,12 +27,13 @@ func (pr *PullRequest) SignMerge(u *User, tmpBasePath, baseCommit, headCommit st
var gitRepo *git.Repository
var err error
Loop:
for _, rule := range rules {
switch rule {
case never:
return false, "", &ErrWontSign{never}
case always:
break
break Loop
case pubkey:
keys, err := ListGPGKeys(u.ID, ListOptions{})
if err != nil {

View File

@ -93,7 +93,7 @@ func (o *OAuth2) userIDFromToken(ctx *macaron.Context) int64 {
}
t, err := models.GetAccessTokenBySHA(tokenSHA)
if err != nil {
if models.IsErrAccessTokenNotExist(err) || models.IsErrAccessTokenEmpty(err) {
if !models.IsErrAccessTokenNotExist(err) && !models.IsErrAccessTokenEmpty(err) {
log.Error("GetAccessTokenBySHA: %v", err)
}
return 0

View File

@ -21,7 +21,7 @@ func handle(data ...queue.Data) {
for _, datum := range data {
opts := datum.(int64)
if err := indexer.Index(opts); err != nil {
log.Error("stats queue idexer.Index(%d) failed: %v", opts, err)
log.Error("stats queue indexer.Index(%d) failed: %v", opts, err)
}
}
}
@ -39,5 +39,11 @@ func initStatsQueue() error {
// UpdateRepoIndexer update a repository's entries in the indexer
func UpdateRepoIndexer(repo *models.Repository) error {
return statsQueue.Push(repo.ID)
if err := statsQueue.Push(repo.ID); err != nil {
if err != queue.ErrAlreadyInQueue {
return err
}
log.Debug("Repo ID: %d already queued", repo.ID)
}
return nil
}

View File

@ -8,7 +8,7 @@ package migrations
import (
"errors"
"github.com/google/go-github/v24/github"
"github.com/google/go-github/v32/github"
)
var (

View File

@ -18,7 +18,7 @@ import (
"code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
"github.com/google/go-github/v24/github"
"github.com/google/go-github/v32/github"
"golang.org/x/oauth2"
)
@ -364,7 +364,7 @@ func (g *GithubDownloaderV3) GetIssues(page, perPage int) ([]*base.Issue, bool,
}
var labels = make([]*base.Label, 0, len(issue.Labels))
for _, l := range issue.Labels {
labels = append(labels, convertGithubLabel(&l))
labels = append(labels, convertGithubLabel(l))
}
var email string
@ -425,8 +425,8 @@ func (g *GithubDownloaderV3) GetComments(issueNumber int64) ([]*base.Comment, er
asc = "asc"
)
opt := &github.IssueListCommentsOptions{
Sort: created,
Direction: asc,
Sort: &created,
Direction: &asc,
ListOptions: github.ListOptions{
PerPage: 100,
},

View File

@ -77,17 +77,20 @@ func Deliver(t *models.HookTask) error {
if err != nil {
return err
}
case http.MethodPut:
switch t.Type {
case models.MATRIX:
req, err = getMatrixHookRequest(t)
if err != nil {
return err
}
default:
return fmt.Errorf("Invalid http method for webhook: [%d] %v", t.ID, t.HTTPMethod)
}
default:
return fmt.Errorf("Invalid http method for webhook: [%d] %v", t.ID, t.HTTPMethod)
}
if t.Type == models.MATRIX {
req, err = getMatrixHookRequest(t)
if err != nil {
return err
}
}
req.Header.Add("X-Gitea-Delivery", t.UUID)
req.Header.Add("X-Gitea-Event", t.EventType.Event())
req.Header.Add("X-Gitea-Signature", t.Signature)

View File

@ -5,6 +5,7 @@
package webhook
import (
"crypto/sha1"
"encoding/json"
"errors"
"fmt"
@ -291,7 +292,14 @@ func getMatrixHookRequest(t *models.HookTask) (*http.Request, error) {
}
t.PayloadContent = string(payload)
req, err := http.NewRequest("POST", t.URL, strings.NewReader(string(payload)))
txnID, err := getMatrixTxnID(payload)
if err != nil {
return nil, fmt.Errorf("getMatrixHookRequest: unable to hash payload: %+v", err)
}
t.URL = fmt.Sprintf("%s/%s", t.URL, txnID)
req, err := http.NewRequest(t.HTTPMethod, t.URL, strings.NewReader(string(payload)))
if err != nil {
return nil, err
}
@ -301,3 +309,14 @@ func getMatrixHookRequest(t *models.HookTask) (*http.Request, error) {
return req, nil
}
// getMatrixTxnID creates a txnID based on the payload to ensure idempotency
func getMatrixTxnID(payload []byte) (string, error) {
h := sha1.New()
_, err := h.Write(payload)
if err != nil {
return "", err
}
return fmt.Sprintf("%x", h.Sum(nil)), nil
}

View File

@ -154,3 +154,32 @@ func TestMatrixHookRequest(t *testing.T) {
assert.Equal(t, "Bearer dummy_access_token", req.Header.Get("Authorization"))
assert.Equal(t, wantPayloadContent, h.PayloadContent)
}
func Test_getTxnID(t *testing.T) {
type args struct {
payload []byte
}
tests := []struct {
name string
args args
want string
wantErr bool
}{
{
name: "dummy payload",
args: args{payload: []byte("Hello World")},
want: "0a4d55a8d778e5022fab701977c5d840bbc486d0",
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := getMatrixTxnID(tt.args.payload)
if (err != nil) != tt.wantErr {
t.Errorf("getMatrixTxnID() error = %v, wantErr %v", err, tt.wantErr)
return
}
assert.Equal(t, tt.want, got)
})
}
}

View File

@ -1169,7 +1169,7 @@ pulls.rebase_conflict=Zusammenführen fehlgeschlagen: Es gab einen Konflikt beim
pulls.unrelated_histories=Zusammenführung fehlgeschlagen: Der Head der Zusammenführung und die Basis haben keinen gemeinsamen Verlauf. Hinweis: Versuche eine andere Strategie
pulls.merge_out_of_date=Zusammenführung fehlgeschlagen: Während der Zusammenführung wurde die Basis aktualisiert. Hinweis: Versuche es erneut.
pulls.push_rejected=Zusammenführen fehlgeschlagen: Der Push wurde mit der folgenden Nachricht abgelehnt:<br>%s<br>Überprüfe die Githooks für dieses Repository
pulls.push_rejected_no_message=Zusammenführen fehlgeschlagen: Der Push wurde abgelehnt, aber es gab keine Fehlermeldung.<br>Überprüfe die Githooks für dieses Repository
pulls.push_rejected_no_message=Merge fehlgeschlagen: Der Push wurde abgelehnt, aber es gab keine Fehlermeldung.<br>Überprüfe die Githooks für dieses Repository
pulls.open_unmerged_pull_exists=`Du kannst diesen Pull-Request nicht erneut öffnen, da noch ein anderer (#%d) mit identischen Eigenschaften offen ist.`
pulls.status_checking=Einige Prüfungen sind noch ausstehend
pulls.status_checks_success=Alle Prüfungen waren erfolgreich
@ -1557,6 +1557,7 @@ settings.protect_merge_whitelist_committers_desc=Erlaube Nutzern oder Teams auf
settings.protect_merge_whitelist_users=Nutzer, die mergen dürfen:
settings.protect_merge_whitelist_teams=Teams, die mergen dürfen:
settings.protect_check_status_contexts=Statusprüfungen aktivieren
settings.protect_check_status_contexts_desc=Statusprüfungen vor dem Zusammenführen erforderlich. Wähle aus, welche Statusprüfungen erfolgreich durchgeführt werden müssen, bevor Branches in einen anderen zusammengeführt werden können, der dieser Regel entspricht. Wenn aktiviert, müssen Commits zuerst auf einen anderen Branch gepusht werden, dann nach bestandener Statusprüfung zusammengeführt oder direkt auf den Branch gepusht werden, der dieser Regel entspricht. Wenn keine Kontext ausgewählt ist, muss der letzte Commit unabhängig vom Kontext erfolgreich sein.
settings.protect_check_status_contexts_list=Statusprüfungen, die in der letzten Woche für dieses Repository gefunden wurden
settings.protect_required_approvals=Erforderliche Zustimmungen:
settings.protect_required_approvals_desc=Erlaube nur Pull-Request mit genügend positiven Reviews zusammenzuführen.
@ -1578,7 +1579,7 @@ settings.protected_branch_deletion=Branch-Schutz deaktivieren
settings.protected_branch_deletion_desc=Wenn du den Branch-Schutz deaktivierst, können alle Nutzer mit Schreibrechten auf den Branch pushen. Fortfahren?
settings.block_rejected_reviews=Merge bei abgelehnten Reviews blockieren
settings.block_rejected_reviews_desc=Mergen ist nicht möglich, wenn Änderungen durch offizielle Reviewer angefragt werden, auch wenn es genügend Zustimmungen gibt.
settings.block_outdated_branch=Zusammenführen blockieren, wenn der Pull-Request veraltet ist
settings.block_outdated_branch=Merge blockieren, wenn der Pull-Request veraltet ist
settings.block_outdated_branch_desc=Die Zusammenführung ist nicht möglich, wenn die Head-Branch hinter der Basis-Branch ist.
settings.default_branch_desc=Wähle einen Standardbranch für Pull-Requests und Code-Commits:
settings.choose_branch=Wähle einen Branch …
@ -2329,6 +2330,7 @@ mirror_sync_create=hat eine neue Referenz des Mirrors <a href="%s/src/%s">%[2]s<
mirror_sync_delete=hat die Referenz des Mirrors <code>%[2]s</code> in <a href="%[1]s">%[3]s</a> synchronisiert und gelöscht
approve_pull_request=`hat <a href="%s/pulls/%s">%s#%[2]s</a> genehmigt`
reject_pull_request=`hat für <a href="%s/pulls/%s">%s#%[2]s</a> Änderungen vorgeschlagen`
publish_release=`hat <a href="%s/releases/tag/%s">"%[4]s"</a> <a href="%[1]s">%[3]s</a> released`
[tool]
ago=vor %s

View File

@ -2330,6 +2330,7 @@ mirror_sync_create=が <a href="%[1]s">%[3]s</a> の新しい参照 <a href="%[1
mirror_sync_delete=が <a href="%[1]s">%[3]s</a> の参照 <code>%[2]s</code> をミラーから反映し、削除しました
approve_pull_request=`が <a href="%s/pulls/%s">%s#%[2]s</a> を承認しました`
reject_pull_request=`が <a href="%s/pulls/%s">%s#%[2]s</a> について変更を求めました`
publish_release=`が <a href="%[1]s">%[3]s</a> の <a href="%[1]s/releases/tag/%[2]s"> "%[4]s" </a> をリリースしました`
[tool]
ago=%s前

View File

@ -19,6 +19,8 @@ create_new=Criar…
user_profile_and_more=Perfil e Configurações...
signed_in_as=Acessado como
enable_javascript=Este site funciona melhor com JavaScript.
toc=Índice
licenses=Licenças
username=Nome de usuário
email=Endereço de e-mail
@ -61,7 +63,7 @@ your_settings=Configurações
all=Todos
sources=Fontes
mirrors=Espelhamentos
collaborative=Coloborativo
collaborative=Colaborativo
forks=Forks
activities=Atividades
@ -70,6 +72,7 @@ issues=Issues
milestones=Marcos
cancel=Cancelar
save=Salvar
add=Adicionar
add_all=Adicionar todos
remove=Remover
@ -82,6 +85,8 @@ loading=Carregando…
error404=A página que você está tentando acessar <strong>não existe</strong> ou <strong>você não está autorizado</strong> a visualizá-la.
[error]
occurred=Ocorreu um erro
report_message=Se você tem certeza de que se trata de um bug do Gitea, por favor, procure a issue no <a href="https://github.com/go-gitea/gitea/issues">GitHub</a> e abra novas issues se necessário.
[startpage]
app_desc=Um serviço de hospedagem Git amigável
@ -201,8 +206,11 @@ my_orgs=Minhas organizações
my_mirrors=Meus espelhamentos
view_home=Ver %s
search_repos=Encontre um repositório…
filter=Outros filtros
show_archived=Arquivado
show_private=Privado
issues.in_your_repos=Em seus repositórios
@ -237,7 +245,7 @@ reset_password_mail_sent_prompt=Um e-mail de confirmação foi enviado para <b>%
active_your_account=Ativar sua conta
account_activated=Conta foi ativada
prohibit_login=Acesso proibido
prohibit_login_desc=Sua conta foi proibida de acessar, por favor entre em conato com o administrador do site.
prohibit_login_desc=Sua conta foi proibida de acessar, por favor entre em contato com o administrador do site.
resent_limit_prompt=Você já solicitou recentemente um e-mail de ativação. Por favor, aguarde 3 minutos e tente novamente.
has_unconfirmed_mail=Oi %s, você possui um endereço de e-mail não confirmado (<b>%s</b>). Se você não recebeu um e-mail de confirmação ou precisa reenviar um novo, clique no botão abaixo.
resend_mail=Clique aqui para reenviar seu e-mail de ativação
@ -377,6 +385,7 @@ follow=Seguir
unfollow=Deixar de seguir
heatmap.loading=Carregando mapa de calor...
user_bio=Biografia
disabled_public_activity=Este usuário desativou a visibilidade pública da atividade.
form.name_reserved=O nome de usuário '%s' está reservado.
form.name_pattern_not_allowed=O padrão de '%s' não é permitido em um nome de usuário.
@ -415,6 +424,9 @@ continue=Continuar
cancel=Cancelar
language=Idioma
ui=Tema
privacy=Privacidade
keep_activity_private=Ocultar a atividade da página de perfil
keep_activity_private_popup=Torna a atividade visível somente para você e os administradores
lookup_avatar_by_mail=Procurar o avatar do endereço de e-mail
federated_avatar_lookup=Busca de avatar federativo
@ -646,6 +658,10 @@ reactions_more=e %d mais
unit_disabled=O administrador do site desabilitou esta seção do repositório.
language_other=Outra
desc.private=Privado
desc.public=Público
desc.internal=Interno
desc.archived=Arquivado
template.items=Itens do modelo
template.git_content=Conteúdo Git (Branch padrão)
@ -669,6 +685,7 @@ form.name_pattern_not_allowed=O padrão de '%s' não é permitido em um nome de
need_auth=Autorização de clone
migrate_type=Tipo de migração
migrate_type_helper=Este repositório será um <span class="text blue">espelhamento</span>
migrate_type_helper_disabled=O administrador do site desabilitou novos espelhamentos.
migrate_items=Itens da migração
migrate_items_wiki=Wiki
migrate_items_milestones=Marcos
@ -821,14 +838,18 @@ issues.desc=Organize relatórios de bugs, tarefas e marcos.
issues.new=Nova issue
issues.new.title_empty=Título não pode ser em branco
issues.new.labels=Etiquetas
issues.new.add_labels_title=Aplicar etiquetas
issues.new.no_label=Sem etiqueta
issues.new.clear_labels=Limpar etiquetas
issues.new.no_items=Nenhum item
issues.new.milestone=Marco
issues.new.add_milestone_title=Definir marco
issues.new.no_milestone=Sem marco
issues.new.clear_milestone=Limpar marco
issues.new.open_milestone=Marcos abertos
issues.new.closed_milestone=Marcos fechados
issues.new.assignees=Responsáveis
issues.new.add_assignees_title=Atribuir usuários
issues.new.clear_assignees=Limpar responsáveis
issues.new.no_assignees=Sem responsável
issues.no_ref=Nenhum branch/tag especificado
@ -918,6 +939,7 @@ issues.ref_from=`de %[1]s`
issues.poster=Autor
issues.collaborator=Colaborador
issues.owner=Proprietário
issues.remove_request_review_block=Não é possível remover a solicitação de revisão
issues.sign_in_require_desc=<a href="%s">Acesse</a> para participar desta conversação.
issues.edit=Editar
issues.cancel=Cancelar
@ -935,6 +957,8 @@ issues.label_deletion_desc=A exclusão desta etiqueta irá removê-la de todas a
issues.label_deletion_success=A etiqueta foi excluída.
issues.label.filter_sort.alphabetically=Alfabeticamente
issues.label.filter_sort.reverse_alphabetically=Alfabeticamente inverso
issues.label.filter_sort.by_size=Menor tamanho
issues.label.filter_sort.reverse_by_size=Maior tamanho
issues.num_participants=%d participante(s)
issues.attachment.open_tab=`Clique para ver "%s" em uma nova aba`
issues.attachment.download=`Clique para baixar "%s"`
@ -1724,9 +1748,14 @@ dashboard.operation_switch=Trocar
dashboard.operation_run=Executar
dashboard.clean_unbind_oauth=Limpar conexões OAuth não vinculadas
dashboard.clean_unbind_oauth_success=Todas as conexões de OAuth não vinculadas foram excluídas.
dashboard.task.process=Tarefa: %[1]s
dashboard.task.unknown=Tarefa desconhecida: %[1]s
dashboard.delete_inactive_accounts=Excluir todas as contas não ativadas
dashboard.delete_inactive_accounts.started=A tarefa de apagar todas as contas não ativadas foi iniciada.
dashboard.delete_repo_archives=Excluir todos os arquivos do repositório
dashboard.delete_missing_repos=Excluir todos os repositórios que não possuem seus arquivos Git
dashboard.delete_generated_repository_avatars=Excluir avatares gerados do repositório
dashboard.update_mirrors=Atualizar espelhamentos
dashboard.git_gc_repos=Coleta de lixo em todos os repositórios
dashboard.resync_all_hooks=Ressincronizar hooks pre-receive, update e post-receive de todos os repositórios.
dashboard.reinit_missing_repos=Reinicializar todos os repositórios Git perdidos cujos registros existem
@ -1795,6 +1824,11 @@ users.still_own_repo=Este usuário ainda possui um ou mais repositórios. Exclua
users.still_has_org=Este usuário é membro de uma organização. Remova o usuário de qualquer organização primeiro.
users.deletion_success=A conta de usuário foi excluída.
emails.filter_sort.email=E-mail
emails.not_updated=Falha ao atualizar o endereço de e-mail solicitado: %v
emails.duplicate_active=Este endereço de e-mail já está ativo para um usuário diferente.
emails.change_email_header=Atualizar Propriedades do E-mail
emails.change_email_text=Você tem certeza que deseja atualizar este endereço de e-mail?
orgs.org_manage_panel=Gerenciamento da organização
orgs.name=Nome
@ -1984,6 +2018,7 @@ config.mailer_user=Usuário
config.mailer_use_sendmail=Usar o Sendmail
config.mailer_sendmail_path=Caminho do Sendmail
config.mailer_sendmail_args=Argumentos extras para o Sendmail
config.mailer_sendmail_timeout=Tempo limite do Sendmail
config.send_test_mail=Enviar e-mail de teste
config.test_mail_failed=Falha ao enviar o e-mail de teste para '%s': %v
config.test_mail_sent=O e-mail de teste foi enviado para '%s'.
@ -2113,6 +2148,7 @@ notices.delete_selected=Excluir seleção
notices.delete_all=Excluir todos os avisos
notices.type=Tipo
notices.type_1=Repositório
notices.type_2=Tarefa
notices.desc=Descrição
notices.op=Op.
notices.delete_success=Os avisos do sistema foram excluídos.
@ -2134,6 +2170,7 @@ transfer_repo=transferiu repositório de <code>%s</code> para <a href="%s">%s</a
push_tag=realizou push da tag <a href="%s/src/tag/%s">%[2]s</a> para <a href="%[1]s">%[3]s</a>
delete_tag=excluiu tag %[2]s de <a href="%[1]s"> %[3]s</a>
delete_branch=excluiu branch %[2]s de <a href="%[1]s">%[3]s</a>
compare_branch=Comparar
compare_commits=Compare %d commits
compare_commits_general=Comparar commits
mirror_sync_push=commits sincronizados para <a href="%[1]s/src/%[2]s">%[3]s</a> em <a href="%[1]s">%[4]s</a> do espelhamento

View File

@ -2330,6 +2330,7 @@ mirror_sync_create=<a href="%s/src/%s">%[2]s</a> referansı <a href="%[1]s">%[3]
mirror_sync_delete=<a href="%[1]s">%[3]s</a> adresindeki <code>%[2]s</code> referansı eşitlendi ve silindi
approve_pull_request=`<a href="%s/pulls/%s">%s#%[2]s</a> onaylandı`
reject_pull_request=`<a href="%s/pulls/%s">%s#%[2]s</a> için değişiklik önerdi `
publish_release=` <a href="%[1]s">%[3]s</a> deposunda <a href="%s/releases/tag/%s"> "%[4]s" </a> sürümü yayınlandı`
[tool]
ago=%s önce

5
package-lock.json generated
View File

@ -4372,6 +4372,11 @@
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.0.2.tgz",
"integrity": "sha512-gPYAU37hYCUhW5euPeR+Y74F7BL+IBsV93j5cvGriSaD1aG6MGsqsV1yamRdrWrb2j3aiZvb0X+UBOWpx3JWtQ=="
},
"escape-goat": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-3.0.0.tgz",
"integrity": "sha512-w3PwNZJwRxlp47QGzhuEBldEqVHHhh8/tIPcl6ecf2Bou99cdAt0knihBV0Ecc7CGxYduXVBDheH1K2oADRlvw=="
},
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",

View File

@ -18,6 +18,7 @@
"css-loader": "4.0.0",
"cssnano-webpack-plugin": "1.0.3",
"dropzone": "5.7.2",
"escape-goat": "3.0.0",
"fast-glob": "3.2.4",
"file-loader": "6.0.0",
"fomantic-ui": "2.8.6",

View File

@ -27,6 +27,7 @@
// - AuthorizationHeaderToken :
// - SudoParam :
// - SudoHeader :
// - TOTPHeader :
//
// SecurityDefinitions:
// BasicAuth:
@ -54,6 +55,11 @@
// name: Sudo
// in: header
// description: Sudo API request as the user provided as the key. Admin privileges are required.
// TOTPHeader:
// type: apiKey
// name: X-GITEA-OTP
// in: header
// description: Must be used in combination with BasicAuth if two-factor authentication is enabled.
//
// swagger:meta
package v1

View File

@ -454,6 +454,7 @@ func MatrixHooksNewPost(ctx *context.Context, form auth.NewMatrixHookForm) {
RepoID: orCtx.RepoID,
URL: fmt.Sprintf("%s/_matrix/client/r0/rooms/%s/send/m.room.message", form.HomeserverURL, form.RoomID),
ContentType: models.ContentTypeJSON,
HTTPMethod: "PUT",
HookEvent: ParseHookEvent(form.WebhookForm),
IsActive: form.Active,
HookTaskType: models.MATRIX,

View File

@ -242,7 +242,7 @@
{{end}}
{{if .Milestone}}
<a class="milestone" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{.Milestone.ID}}&assignee={{$.AssigneeID}}">
<a class="milestone" href="{{$.RepoLink}}/milestone/{{.Milestone.ID}}">
{{svg "octicon-milestone" 16}} {{.Milestone.Name}}
</a>
{{end}}

View File

@ -15551,6 +15551,12 @@
"name": "sudo",
"in": "query"
},
"TOTPHeader": {
"description": "Must be used in combination with BasicAuth if two-factor authentication is enabled.",
"type": "apiKey",
"name": "X-GITEA-OTP",
"in": "header"
},
"Token": {
"type": "apiKey",
"name": "token",
@ -15575,6 +15581,9 @@
},
{
"SudoHeader": []
},
{
"TOTPHeader": []
}
]
}

View File

@ -142,7 +142,7 @@
{{$.i18n.Tr .GetLastEventLabelFake $timeStr (.Poster.GetDisplayName|Escape) | Safe}}
{{end}}
{{if .Milestone}}
<a class="milestone" href="{{AppSubUrl}}/{{.Repo.Owner.Name}}/{{.Repo.Name}}{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{.Milestone.ID}}&assignee={{$.AssigneeID}}">
<a class="milestone" href="{{AppSubUrl}}/{{.Repo.Owner.Name}}/{{.Repo.Name}}/milestone/{{.Milestone.ID}}">
{{svg "octicon-milestone" 16}} {{.Milestone.Name}}
</a>
{{end}}

View File

@ -1,230 +0,0 @@
// 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
}

View File

@ -1,457 +0,0 @@
// 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)
}

View File

@ -1,155 +0,0 @@
// 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)
}

View File

@ -1,160 +0,0 @@
// 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)
}

View File

@ -1,174 +0,0 @@
// 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 teams 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
}

View File

@ -9,22 +9,31 @@
# their employer, as appropriate).
178inaba <masahiro.furudate@gmail.com>
2BFL <imqksl@gmail.com>
413x <dedifferentiator@gmail.com>
Abhinav Gupta <mail@abhinavg.net>
adrienzieba <adrien.zieba@appdirect.com>
Ahmed Hagy <a.akram93@gmail.com>
Aidan Steele <aidan.steele@glassechidna.com.au>
Ainsley Chong <ainsley.chong@gmail.com>
ajz01 <azdenek@yahoo.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>
Alex Orr <Alexorr.CSE@gmail.com>
Alexander Harkness <me@bearbin.net>
Allen Sun <shlallen1990@gmail.com>
Amey Sakhadeo <me@ameyms.com>
Anders Janmyr <anders@janmyr.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>
angie pinilla <angelinepinilla@gmail.com>
anjanashenoy <anjanashenoy1@gmail.com>
Anshuman Bhartiya <anshuman.bhartiya@gmail.com>
Antoine <antoine.tu@mail.mcgill.ca>
Antoine Pelisse <apelisse@gmail.com>
@ -33,6 +42,7 @@ appilon <apilon@hashicorp.com>
Aravind <aravindkp@outlook.in>
Arda Kuyumcu <kuyumcuarda@gmail.com>
Arıl Bozoluk <arilbozoluk@hotmail.com>
Austin Burdine <acburdine@gmail.com>
Austin Dizzy <dizzy@wow.com>
Ben Batha <bhbatha@gmail.com>
Benjamen Keroack <benjamen@dollarshaveclub.com>
@ -47,13 +57,18 @@ Brandon Cook <phylake@gmail.com>
Brian Egizi <brian@mojotech.com>
Bryan Boreham <bryan@weave.works>
Cami Diez <diezcami@gmail.com>
Carl Johnson <me@carlmjohnson.net>
Carlos Alexandro Becker <caarlos0@gmail.com>
Carlos Tadeu Panato Junior <ctadeu@gmail.com>
chandresh-pancholi <chandreshpancholi007@gmail.com>
Charles Fenwick Elliott <Charles@FenwickElliott.io>
Charlie Yan <charlieyan08@gmail.com>
Chris King <chriskingnet@gmail.com>
Chris Raborg <craborg57@gmail.com>
Chris Roche <chris@vsco.co>
Chris Schaefer <chris@dtzq.com>
chrisforrette <chris@chrisforrette.com>
Christian Muehlhaeuser <muesli@gmail.com>
Christoph Sassenberg <defsprite@gmail.com>
Colin Misare <github.com/cmisare>
Craig Peterson <cpeterson@stackoverflow.com>
@ -61,10 +76,14 @@ Cristian Maglie <c.maglie@bug.st>
Daehyeok Mun <daehyeok@gmail.com>
Daniel Leavitt <daniel.leavitt@gmail.com>
Daniel Nilsson <daniel.nilsson1989@gmail.com>
Daoq <masseto2002@gmail.com>
Dave Du Cros <davidducros@gmail.com>
Dave Henderson <dhenderson@gmail.com>
Dave Protasowski <dprotaso@gmail.com>
David Deng <daviddengcn@gmail.com>
David Jannotta <djannotta@gmail.com>
David Ji <github.com/davidji99>
David Lopez Reyes <davidlopezre@gmail.com>
Davide Zipeto <dawez1@gmail.com>
Dennis Webb <dennis@bluesentryit.com>
Dhi Aurrahman <diorahman@rockybars.com>
@ -74,22 +93,26 @@ dmnlk <seikima2demon@gmail.com>
Don Petersen <don@donpetersen.net>
Doug Turner <doug.turner@gmail.com>
Drew Fradette <drew.fradette@gmail.com>
Eivind <eivindkn@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>
Evan Elias <evanjelias@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>
Francisco Guimarães <francisco.cpg@gmail.com>
Fredrik Jönsson <fredrik.jonsson@izettle.com>
Garrett Squire <garrettsquire@gmail.com>
George Kontridze <george.kontridze@gmail.com>
Georgy Buranov <gburanov@gmail.com>
Glen Mailer <glenjamin@gmail.com>
Gnahz <p@oath.pl>
Google Inc.
Grachev Mikhail <work@mgrachev.com>
@ -99,13 +122,16 @@ 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 <haya14busa@gmail.com>
haya14busa <hayabusa1419@gmail.com>
Huy Tr <kingbazoka@gmail.com>
huydx <doxuanhuy@gmail.com>
i2bskn <i2bskn@gmail.com>
Ioannis Georgoulas <igeorgoulas21@gmail.com>
Isao Jonas <isao.jonas@gmail.com>
isqua <isqua@isqua.ru>
Jameel Haffejee <RC1140@republiccommandos.co.za>
James Cockbain <james.cockbain@ibm.com>
Jan Kosecki <jan.kosecki91@gmail.com>
Javier Campanini <jcampanini@palantir.com>
Jens Rantil <jens.rantil@gmail.com>
@ -117,6 +143,7 @@ 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 Brockopp <jdbro94@gmail.com>
Jordan Sussman <jordansail22@gmail.com>
Joshua Bezaleel Abednego <joshua.bezaleel@gmail.com>
JP Phillips <jonphill9@gmail.com>
@ -124,11 +151,12 @@ 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>
Junya Kono <junya03dance@gmail.com>
Justin Abrahms <justin@abrah.ms>
Jusung Lee <e.jusunglee@gmail.com>
jzhoucliqr <jzhou@cliqr.com>
kadern0 <kaderno@gmail.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>
@ -137,15 +165,21 @@ Kookheon Kwon <kucuny@gmail.com>
Krzysztof Kowalczyk <kkowalczyk@gmail.com>
Kshitij Saraogi <KshitijSaraogi@gmail.com>
kyokomi <kyoko1220adword@gmail.com>
Laurent Verdoïa <verdoialaurent@gmail.com>
Liam Galvin <liam@liam-galvin.co.uk>
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>
lynn [they] <lynncyrin@gmail.com>
Maksim Zhylinski <uzzable@gmail.com>
Mark Tareshawty <tarebyte@github.com>
Martin-Louis Bright <mlbright@gmail.com>
Martins Sipenko <martins.sipenko@gmail.com>
Marwan Sulaiman <marwan.sameer@gmail.com>
Masayuki Izumi <m@izum.in>
Mat Geist <matgeist@gmail.com>
Matt <alpmatthew@gmail.com>
Matt Brender <mjbrender@gmail.com>
@ -155,6 +189,7 @@ 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>
Nadav Kaner <nadavkaner1@gmail.com>
Nathan VanBenschoten <nvanbenschoten@gmail.com>
Navaneeth Suresh <navaneeths1998@gmail.com>
Neil O'Toole <neilotoole@apache.org>
@ -163,6 +198,7 @@ Nick Spragg <nick.spragg@bbc.co.uk>
Nikhita Raghunath <nikitaraghunath@gmail.com>
Noah Zoschke <noah+sso2@convox.com>
ns-cweber <cweber@narrativescience.com>
Ole Orhagen <ole.orhagen@northern.tech>
Oleg Kovalov <iamolegkovalov@gmail.com>
Ondřej Kupka <ondra.cap@gmail.com>
Palash Nigam <npalash25@gmail.com>
@ -170,29 +206,43 @@ Panagiotis Moustafellos <pmoust@gmail.com>
Parham Alvani <parham.alvani@gmail.com>
Parker Moore <parkrmoore@gmail.com>
parkhyukjun89 <park.hyukjun89@gmail.com>
Patrick DeVivo <patrick.devivo@gmail.com>
Patrick Marabeas <patrick@marabeas.io>
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>
Pratik Mallya <pratik.mallya@gmail.com>
Qais Patankar <qaisjp@gmail.com>
Quang Le Hong <iamquang95@gmail.com>
Quentin Leffray <fiahil@gmail.com>
Quinn Slack <qslack@qslack.com>
Rackspace US, Inc.
Radek Simko <radek.simko@gmail.com>
Radliński Ignacy <radlinsk@student.agh.edu.pl>
Rajat Jindal <rajatjindal83@gmail.com>
Rajendra arora <rajendraarora16@yahoo.com>
Ranbir Singh <binkkatal.r@gmail.com>
Ravi Shekhar Jethani <rsjethani@gmail.com>
RaviTeja Pothana <ravi-teja@live.com>
rc1140 <jameel@republiccommandos.co.za>
Red Hat, Inc.
Reinier Timmer <reinier.timmer@ah.nl>
Ricco Førgaard <ricco@fiskeben.dk>
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>
Ryo Nakao <nakabonne@gmail.com>
Safwan Olaimat <safwan.olaimat@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 Knape <s.knape88@gmail.com>
Sander van Harmelen <svanharmelen@schubergphilis.com>
Sanket Payghan <sanket.payghan8@gmail.com>
Sarasa Kisaragi <lingsamuelgrace@gmail.com>
@ -200,30 +250,46 @@ 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>
Sergio Garcia <sergio.garcia@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>
Shibasis Patel <patelshibasis@gmail.com>
Shrikrishna Singh <krishnasingh.ss30@gmail.com>
sona-tar <sona.zip@gmail.com>
SoundCloud, Ltd.
Sridhar Mocherla <srmocher@microsoft.com>
SriVignessh Pss <sriknowledge@gmail.com>
Stefan Sedich <stefan.sedich@gmail.com>
Stian Eikeland <stian@eikeland.se>
Suhaib Mujahid <suhaibmujahid@gmail.com>
Szymon Kodrebski <simonkey007@gmail.com>
Takayuki Watanabe <takanabe.w@gmail.com>
Taketoshi Fujiwara <taketoshi.fujiwara@gmail.com>
Tasya Aditya Rukmana <tadityar@gmail.com>
Thomas Bruyelle <thomas.bruyelle@gmail.com>
Timothée Peignier <timothee.peignier@tryphon.org>
tkhandel <tarunkhandelwal.iitr@gmail.com>
Trey Tacon <ttacon@gmail.com>
ttacon <ttacon@gmail.com>
Vaibhav Singh <vaibhav.singh.14cse@bml.edu.in>
Varadarajan Aravamudhan <varadaraajan@gmail.com>
Victor Castell <victor@victorcastell.com>
Victor Vrantchan <vrancean+github@gmail.com>
vikkyomkar <vikky.omkar@samsung.com>
Vlad Ungureanu <vladu@palantir.com>
Wasim Thabraze <wasim@thabraze.me>
Weslei Juan Moser Pereira <wesleimsr@gmail.com>
Will Maier <wcmaier@gmail.com>
Willem D'Haeseleer <dhwillem@gmail.com>
William Bailey <mail@williambailey.org.uk>
William Cooke <pipeston@gmail.com>
xibz <impactbchang@gmail.com>
Yann Malet <yann.malet@gmail.com>
Yannick Utard <yannickutard@gmail.com>
Yicheng Qin <qycqycqycqycqyc@gmail.com>
Yosuke Akatsuka <yosuke.akatsuka@access-company.com>
Yumikiyo Osanai <yumios.art@gmail.com>
Zach Latta <zach@zachlatta.com>

View File

@ -0,0 +1,12 @@
// Copyright 2020 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
// ActionsService handles communication with the actions related
// methods of the GitHub API.
//
// GitHub API docs: https://developer.github.com/v3/actions/
type ActionsService service

View File

@ -0,0 +1,164 @@
// Copyright 2020 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/http"
"net/url"
)
// Artifact reprents a GitHub artifact. Artifacts allow sharing
// data between jobs in a workflow and provide storage for data
// once a workflow is complete.
//
// GitHub API docs: https://developer.github.com/v3/actions/artifacts/
type Artifact struct {
ID *int64 `json:"id,omitempty"`
NodeID *string `json:"node_id,omitempty"`
Name *string `json:"name,omitempty"`
SizeInBytes *int64 `json:"size_in_bytes,omitempty"`
ArchiveDownloadURL *string `json:"archive_download_url,omitempty"`
Expired *bool `json:"expired,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
ExpiresAt *Timestamp `json:"expires_at,omitempty"`
}
// ArtifactList represents a list of GitHub artifacts.
//
// GitHub API docs: https://developer.github.com/v3/actions/artifacts/
type ArtifactList struct {
TotalCount *int64 `json:"total_count,omitempty"`
Artifacts []*Artifact `json:"artifacts,omitempty"`
}
// ListArtifacts lists all artifacts that belong to a repository.
//
// GitHub API docs: https://developer.github.com/v3/actions/artifacts/#list-artifacts-for-a-repository
func (s *ActionsService) ListArtifacts(ctx context.Context, owner, repo string, opts *ListOptions) (*ArtifactList, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/artifacts", owner, repo)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
artifactList := new(ArtifactList)
resp, err := s.client.Do(ctx, req, artifactList)
if err != nil {
return nil, resp, err
}
return artifactList, resp, nil
}
// ListWorkflowRunArtifacts lists all artifacts that belong to a workflow run.
//
// GitHub API docs: https://developer.github.com/v3/actions/artifacts/#list-workflow-run-artifacts
func (s *ActionsService) ListWorkflowRunArtifacts(ctx context.Context, owner, repo string, runID int64, opts *ListOptions) (*ArtifactList, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/artifacts", owner, repo, runID)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
artifactList := new(ArtifactList)
resp, err := s.client.Do(ctx, req, artifactList)
if err != nil {
return nil, resp, err
}
return artifactList, resp, nil
}
// GetArtifact gets a specific artifact for a workflow run.
//
// GitHub API docs: https://developer.github.com/v3/actions/artifacts/#get-an-artifact
func (s *ActionsService) GetArtifact(ctx context.Context, owner, repo string, artifactID int64) (*Artifact, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/artifacts/%v", owner, repo, artifactID)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
artifact := new(Artifact)
resp, err := s.client.Do(ctx, req, artifact)
if err != nil {
return nil, resp, err
}
return artifact, resp, nil
}
// DownloadArtifact gets a redirect URL to download an archive for a repository.
//
// GitHub API docs: https://developer.github.com/v3/actions/artifacts/#download-an-artifact
func (s *ActionsService) DownloadArtifact(ctx context.Context, owner, repo string, artifactID int64, followRedirects bool) (*url.URL, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/artifacts/%v/zip", owner, repo, artifactID)
resp, err := s.getDownloadArtifactFromURL(ctx, u, followRedirects)
if err != nil {
return nil, nil, err
}
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), nil
}
func (s *ActionsService) getDownloadArtifactFromURL(ctx context.Context, u string, followRedirects bool) (*http.Response, error) {
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return 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, err
}
resp.Body.Close()
// If redirect response is returned, follow it
if followRedirects && resp.StatusCode == http.StatusMovedPermanently {
u = resp.Header.Get("Location")
resp, err = s.getDownloadArtifactFromURL(ctx, u, false)
}
return resp, err
}
// DeleteArtifact deletes a workflow run artifact.
//
// GitHub API docs: https://developer.github.com/v3/actions/artifacts/#delete-an-artifact
func (s *ActionsService) DeleteArtifact(ctx context.Context, owner, repo string, artifactID int64) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/artifacts/%v", owner, repo, artifactID)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}

View File

@ -0,0 +1,277 @@
// Copyright 2020 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"
)
// RunnerApplicationDownload represents a binary for the self-hosted runner application that can be downloaded.
type RunnerApplicationDownload struct {
OS *string `json:"os,omitempty"`
Architecture *string `json:"architecture,omitempty"`
DownloadURL *string `json:"download_url,omitempty"`
Filename *string `json:"filename,omitempty"`
}
// ListRunnerApplicationDownloads lists self-hosted runner application binaries that can be downloaded and run.
//
// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#list-runner-applications-for-a-repository
func (s *ActionsService) ListRunnerApplicationDownloads(ctx context.Context, owner, repo string) ([]*RunnerApplicationDownload, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/runners/downloads", owner, repo)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
var rads []*RunnerApplicationDownload
resp, err := s.client.Do(ctx, req, &rads)
if err != nil {
return nil, resp, err
}
return rads, resp, nil
}
// RegistrationToken represents a token that can be used to add a self-hosted runner to a repository.
type RegistrationToken struct {
Token *string `json:"token,omitempty"`
ExpiresAt *Timestamp `json:"expires_at,omitempty"`
}
// CreateRegistrationToken creates a token that can be used to add a self-hosted runner.
//
// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#create-a-registration-token-for-a-repository
func (s *ActionsService) CreateRegistrationToken(ctx context.Context, owner, repo string) (*RegistrationToken, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/runners/registration-token", owner, repo)
req, err := s.client.NewRequest("POST", u, nil)
if err != nil {
return nil, nil, err
}
registrationToken := new(RegistrationToken)
resp, err := s.client.Do(ctx, req, registrationToken)
if err != nil {
return nil, resp, err
}
return registrationToken, resp, nil
}
// Runner represents a self-hosted runner registered with a repository.
type Runner struct {
ID *int64 `json:"id,omitempty"`
Name *string `json:"name,omitempty"`
OS *string `json:"os,omitempty"`
Status *string `json:"status,omitempty"`
}
// Runners represents a collection of self-hosted runners for a repository.
type Runners struct {
TotalCount int `json:"total_count"`
Runners []*Runner `json:"runners"`
}
// ListRunners lists all the self-hosted runners for a repository.
//
// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#list-self-hosted-runners-for-a-repository
func (s *ActionsService) ListRunners(ctx context.Context, owner, repo string, opts *ListOptions) (*Runners, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/runners", owner, repo)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
runners := &Runners{}
resp, err := s.client.Do(ctx, req, &runners)
if err != nil {
return nil, resp, err
}
return runners, resp, nil
}
// GetRunner gets a specific self-hosted runner for a repository using its runner ID.
//
// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#get-a-self-hosted-runner-for-a-repository
func (s *ActionsService) GetRunner(ctx context.Context, owner, repo string, runnerID int64) (*Runner, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/runners/%v", owner, repo, runnerID)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
runner := new(Runner)
resp, err := s.client.Do(ctx, req, runner)
if err != nil {
return nil, resp, err
}
return runner, resp, nil
}
// RemoveToken represents a token that can be used to remove a self-hosted runner from a repository.
type RemoveToken struct {
Token *string `json:"token,omitempty"`
ExpiresAt *Timestamp `json:"expires_at,omitempty"`
}
// CreateRemoveToken creates a token that can be used to remove a self-hosted runner from a repository.
//
// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#create-a-remove-token-for-a-repository
func (s *ActionsService) CreateRemoveToken(ctx context.Context, owner, repo string) (*RemoveToken, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/runners/remove-token", owner, repo)
req, err := s.client.NewRequest("POST", u, nil)
if err != nil {
return nil, nil, err
}
removeToken := new(RemoveToken)
resp, err := s.client.Do(ctx, req, removeToken)
if err != nil {
return nil, resp, err
}
return removeToken, resp, nil
}
// RemoveRunner forces the removal of a self-hosted runner in a repository using the runner id.
//
// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#delete-a-self-hosted-runner-from-a-repository
func (s *ActionsService) RemoveRunner(ctx context.Context, owner, repo string, runnerID int64) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/runners/%v", owner, repo, runnerID)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// ListOrganizationRunnerApplicationDownloads lists self-hosted runner application binaries that can be downloaded and run.
//
// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#list-runner-applications-for-an-organization
func (s *ActionsService) ListOrganizationRunnerApplicationDownloads(ctx context.Context, owner string) ([]*RunnerApplicationDownload, *Response, error) {
u := fmt.Sprintf("orgs/%v/actions/runners/downloads", owner)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
var rads []*RunnerApplicationDownload
resp, err := s.client.Do(ctx, req, &rads)
if err != nil {
return nil, resp, err
}
return rads, resp, nil
}
// CreateOrganizationRegistrationToken creates a token that can be used to add a self-hosted runner to an organization.
//
// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#create-a-registration-token-for-an-organization
func (s *ActionsService) CreateOrganizationRegistrationToken(ctx context.Context, owner string) (*RegistrationToken, *Response, error) {
u := fmt.Sprintf("orgs/%v/actions/runners/registration-token", owner)
req, err := s.client.NewRequest("POST", u, nil)
if err != nil {
return nil, nil, err
}
registrationToken := new(RegistrationToken)
resp, err := s.client.Do(ctx, req, registrationToken)
if err != nil {
return nil, resp, err
}
return registrationToken, resp, nil
}
// ListOrganizationRunners lists all the self-hosted runners for an organization.
//
// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#list-self-hosted-runners-for-an-organization
func (s *ActionsService) ListOrganizationRunners(ctx context.Context, owner string, opts *ListOptions) (*Runners, *Response, error) {
u := fmt.Sprintf("orgs/%v/actions/runners", owner)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
runners := &Runners{}
resp, err := s.client.Do(ctx, req, &runners)
if err != nil {
return nil, resp, err
}
return runners, resp, nil
}
// GetOrganizationRunner gets a specific self-hosted runner for an organization using its runner ID.
//
// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#get-a-self-hosted-runner-for-an-organization
func (s *ActionsService) GetOrganizationRunner(ctx context.Context, owner string, runnerID int64) (*Runner, *Response, error) {
u := fmt.Sprintf("orgs/%v/actions/runners/%v", owner, runnerID)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
runner := new(Runner)
resp, err := s.client.Do(ctx, req, runner)
if err != nil {
return nil, resp, err
}
return runner, resp, nil
}
// CreateOrganizationRemoveToken creates a token that can be used to remove a self-hosted runner from an organization.
//
// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#create-a-remove-token-for-an-organization
func (s *ActionsService) CreateOrganizationRemoveToken(ctx context.Context, owner string) (*RemoveToken, *Response, error) {
u := fmt.Sprintf("orgs/%v/actions/runners/remove-token", owner)
req, err := s.client.NewRequest("POST", u, nil)
if err != nil {
return nil, nil, err
}
removeToken := new(RemoveToken)
resp, err := s.client.Do(ctx, req, removeToken)
if err != nil {
return nil, resp, err
}
return removeToken, resp, nil
}
// RemoveOrganizationRunner forces the removal of a self-hosted runner from an organization using the runner id.
//
// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#delete-a-self-hosted-runner-from-an-organization
func (s *ActionsService) RemoveOrganizationRunner(ctx context.Context, owner string, runnerID int64) (*Response, error) {
u := fmt.Sprintf("orgs/%v/actions/runners/%v", owner, runnerID)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}

View File

@ -0,0 +1,299 @@
// Copyright 2020 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"
)
// PublicKey represents the public key that should be used to encrypt secrets.
type PublicKey struct {
KeyID *string `json:"key_id"`
Key *string `json:"key"`
}
// GetRepoPublicKey gets a public key that should be used for secret encryption.
//
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#get-a-repository-public-key
func (s *ActionsService) GetRepoPublicKey(ctx context.Context, owner, repo string) (*PublicKey, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/secrets/public-key", owner, repo)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
pubKey := new(PublicKey)
resp, err := s.client.Do(ctx, req, pubKey)
if err != nil {
return nil, resp, err
}
return pubKey, resp, nil
}
// GetOrgPublicKey gets a public key that should be used for secret encryption.
//
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#get-an-organization-public-key
func (s *ActionsService) GetOrgPublicKey(ctx context.Context, org string) (*PublicKey, *Response, error) {
u := fmt.Sprintf("orgs/%v/actions/secrets/public-key", org)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
pubKey := new(PublicKey)
resp, err := s.client.Do(ctx, req, pubKey)
if err != nil {
return nil, resp, err
}
return pubKey, resp, nil
}
// Secret represents a repository action secret.
type Secret struct {
Name string `json:"name"`
CreatedAt Timestamp `json:"created_at"`
UpdatedAt Timestamp `json:"updated_at"`
Visibility string `json:"visibility,omitempty"`
SelectedRepositoriesURL string `json:"selected_repositories_url,omitempty"`
}
// Secrets represents one item from the ListSecrets response.
type Secrets struct {
TotalCount int `json:"total_count"`
Secrets []*Secret `json:"secrets"`
}
// ListRepoSecrets lists all secrets available in a repository
// without revealing their encrypted values.
//
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#list-repository-secrets
func (s *ActionsService) ListRepoSecrets(ctx context.Context, owner, repo string, opts *ListOptions) (*Secrets, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/secrets", owner, repo)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
secrets := new(Secrets)
resp, err := s.client.Do(ctx, req, &secrets)
if err != nil {
return nil, resp, err
}
return secrets, resp, nil
}
// GetRepoSecret gets a single repository secret without revealing its encrypted value.
//
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#get-a-repository-secret
func (s *ActionsService) GetRepoSecret(ctx context.Context, owner, repo, name string) (*Secret, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/secrets/%v", owner, repo, name)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
secret := new(Secret)
resp, err := s.client.Do(ctx, req, secret)
if err != nil {
return nil, resp, err
}
return secret, resp, nil
}
// SelectedRepoIDs are the repository IDs that have access to the secret.
type SelectedRepoIDs []int64
// EncryptedSecret represents a secret that is encrypted using a public key.
//
// The value of EncryptedValue must be your secret, encrypted with
// LibSodium (see documentation here: https://libsodium.gitbook.io/doc/bindings_for_other_languages)
// using the public key retrieved using the GetPublicKey method.
type EncryptedSecret struct {
Name string `json:"-"`
KeyID string `json:"key_id"`
EncryptedValue string `json:"encrypted_value"`
Visibility string `json:"visibility,omitempty"`
SelectedRepositoryIDs SelectedRepoIDs `json:"selected_repository_ids,omitempty"`
}
// CreateOrUpdateRepoSecret creates or updates a repository secret with an encrypted value.
//
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#create-or-update-a-repository-secret
func (s *ActionsService) CreateOrUpdateRepoSecret(ctx context.Context, owner, repo string, eSecret *EncryptedSecret) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/secrets/%v", owner, repo, eSecret.Name)
req, err := s.client.NewRequest("PUT", u, eSecret)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// DeleteRepoSecret deletes a secret in a repository using the secret name.
//
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#delete-a-repository-secret
func (s *ActionsService) DeleteRepoSecret(ctx context.Context, owner, repo, name string) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/secrets/%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)
}
// ListOrgSecrets lists all secrets available in an organization
// without revealing their encrypted values.
//
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#list-organization-secrets
func (s *ActionsService) ListOrgSecrets(ctx context.Context, org string, opts *ListOptions) (*Secrets, *Response, error) {
u := fmt.Sprintf("orgs/%v/actions/secrets", org)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
secrets := new(Secrets)
resp, err := s.client.Do(ctx, req, &secrets)
if err != nil {
return nil, resp, err
}
return secrets, resp, nil
}
// GetOrgSecret gets a single organization secret without revealing its encrypted value.
//
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#get-an-organization-secret
func (s *ActionsService) GetOrgSecret(ctx context.Context, org, name string) (*Secret, *Response, error) {
u := fmt.Sprintf("orgs/%v/actions/secrets/%v", org, name)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
secret := new(Secret)
resp, err := s.client.Do(ctx, req, secret)
if err != nil {
return nil, resp, err
}
return secret, resp, nil
}
// CreateOrUpdateOrgSecret creates or updates an organization secret with an encrypted value.
//
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#create-or-update-an-organization-secret
func (s *ActionsService) CreateOrUpdateOrgSecret(ctx context.Context, org string, eSecret *EncryptedSecret) (*Response, error) {
u := fmt.Sprintf("orgs/%v/actions/secrets/%v", org, eSecret.Name)
req, err := s.client.NewRequest("PUT", u, eSecret)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// SelectedReposList represents the list of repositories selected for an organization secret.
type SelectedReposList struct {
TotalCount *int `json:"total_count,omitempty"`
Repositories []*Repository `json:"repositories,omitempty"`
}
// ListSelectedReposForOrgSecret lists all repositories that have access to a secret.
//
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#list-selected-repositories-for-an-organization-secret
func (s *ActionsService) ListSelectedReposForOrgSecret(ctx context.Context, org, name string) (*SelectedReposList, *Response, error) {
u := fmt.Sprintf("orgs/%v/actions/secrets/%v/repositories", org, name)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
result := new(SelectedReposList)
resp, err := s.client.Do(ctx, req, result)
if err != nil {
return nil, resp, err
}
return result, resp, nil
}
// SetSelectedReposForOrgSecret sets the repositories that have access to a secret.
//
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#set-selected-repositories-for-an-organization-secret
func (s *ActionsService) SetSelectedReposForOrgSecret(ctx context.Context, org, name string, ids SelectedRepoIDs) (*Response, error) {
u := fmt.Sprintf("orgs/%v/actions/secrets/%v/repositories", org, name)
type repoIDs struct {
SelectedIDs SelectedRepoIDs `json:"selected_repository_ids,omitempty"`
}
req, err := s.client.NewRequest("PUT", u, repoIDs{SelectedIDs: ids})
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// AddSelectedRepoToOrgSecret adds a repository to an organization secret.
//
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#add-selected-repository-to-an-organization-secret
func (s *ActionsService) AddSelectedRepoToOrgSecret(ctx context.Context, org, name string, repo *Repository) (*Response, error) {
u := fmt.Sprintf("orgs/%v/actions/secrets/%v/repositories/%v", org, name, *repo.ID)
req, err := s.client.NewRequest("PUT", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// RemoveSelectedRepoFromOrgSecret removes a repository from an organization secret.
//
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#remove-selected-repository-from-an-organization-secret
func (s *ActionsService) RemoveSelectedRepoFromOrgSecret(ctx context.Context, org, name string, repo *Repository) (*Response, error) {
u := fmt.Sprintf("orgs/%v/actions/secrets/%v/repositories/%v", org, name, *repo.ID)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// DeleteOrgSecret deletes a secret in an organization using the secret name.
//
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#delete-an-organization-secret
func (s *ActionsService) DeleteOrgSecret(ctx context.Context, org, name string) (*Response, error) {
u := fmt.Sprintf("orgs/%v/actions/secrets/%v", org, name)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}

View File

@ -0,0 +1,149 @@
// Copyright 2020 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/http"
"net/url"
)
// TaskStep represents a single task step from a sequence of tasks of a job.
type TaskStep struct {
Name *string `json:"name,omitempty"`
Status *string `json:"status,omitempty"`
Conclusion *string `json:"conclusion,omitempty"`
Number *int64 `json:"number,omitempty"`
StartedAt *Timestamp `json:"started_at,omitempty"`
CompletedAt *Timestamp `json:"completed_at,omitempty"`
}
// WorkflowJob represents a repository action workflow job.
type WorkflowJob struct {
ID *int64 `json:"id,omitempty"`
RunID *int64 `json:"run_id,omitempty"`
RunURL *string `json:"run_url,omitempty"`
NodeID *string `json:"node_id,omitempty"`
HeadSHA *string `json:"head_sha,omitempty"`
URL *string `json:"url,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
Status *string `json:"status,omitempty"`
Conclusion *string `json:"conclusion,omitempty"`
StartedAt *Timestamp `json:"started_at,omitempty"`
CompletedAt *Timestamp `json:"completed_at,omitempty"`
Name *string `json:"name,omitempty"`
Steps []*TaskStep `json:"steps,omitempty"`
CheckRunURL *string `json:"check_run_url,omitempty"`
}
// Jobs represents a slice of repository action workflow job.
type Jobs struct {
TotalCount *int `json:"total_count,omitempty"`
Jobs []*WorkflowJob `json:"jobs,omitempty"`
}
// ListWorkflowJobsOptions specifies optional parameters to ListWorkflowJobs.
type ListWorkflowJobsOptions struct {
// Filter specifies how jobs should be filtered by their completed_at timestamp.
// Possible values are:
// latest - Returns jobs from the most recent execution of the workflow run
// all - Returns all jobs for a workflow run, including from old executions of the workflow run
//
// Default value is "latest".
Filter string `url:"filter,omitempty"`
ListOptions
}
// ListWorkflowJobs lists all jobs for a workflow run.
//
// GitHub API docs: https://developer.github.com/v3/actions/workflow-jobs/#list-jobs-for-a-workflow-run
func (s *ActionsService) ListWorkflowJobs(ctx context.Context, owner, repo string, runID int64, opts *ListWorkflowJobsOptions) (*Jobs, *Response, error) {
u := fmt.Sprintf("repos/%s/%s/actions/runs/%v/jobs", owner, repo, runID)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
jobs := new(Jobs)
resp, err := s.client.Do(ctx, req, &jobs)
if err != nil {
return nil, resp, err
}
return jobs, resp, nil
}
// GetWorkflowJobByID gets a specific job in a workflow run by ID.
//
// GitHub API docs: https://developer.github.com/v3/actions/workflow-jobs/#get-a-job-for-a-workflow-run
func (s *ActionsService) GetWorkflowJobByID(ctx context.Context, owner, repo string, jobID int64) (*WorkflowJob, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/jobs/%v", owner, repo, jobID)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
job := new(WorkflowJob)
resp, err := s.client.Do(ctx, req, job)
if err != nil {
return nil, resp, err
}
return job, resp, nil
}
// GetWorkflowJobLogs gets a redirect URL to download a plain text file of logs for a workflow job.
//
// GitHub API docs: https://developer.github.com/v3/actions/workflow-jobs/#download-job-logs-for-a-workflow-run
func (s *ActionsService) GetWorkflowJobLogs(ctx context.Context, owner, repo string, jobID int64, followRedirects bool) (*url.URL, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/jobs/%v/logs", owner, repo, jobID)
resp, err := s.getWorkflowLogsFromURL(ctx, u, followRedirects)
if err != nil {
return nil, nil, err
}
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
}
func (s *ActionsService) getWorkflowLogsFromURL(ctx context.Context, u string, followRedirects bool) (*http.Response, error) {
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return 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, err
}
resp.Body.Close()
// If redirect response is returned, follow it
if followRedirects && resp.StatusCode == http.StatusMovedPermanently {
u = resp.Header.Get("Location")
resp, err = s.getWorkflowLogsFromURL(ctx, u, false)
}
return resp, err
}

View File

@ -0,0 +1,235 @@
// Copyright 2020 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/http"
"net/url"
)
// WorkflowRun represents a repository action workflow run.
type WorkflowRun struct {
ID *int64 `json:"id,omitempty"`
NodeID *string `json:"node_id,omitempty"`
HeadBranch *string `json:"head_branch,omitempty"`
HeadSHA *string `json:"head_sha,omitempty"`
RunNumber *int `json:"run_number,omitempty"`
Event *string `json:"event,omitempty"`
Status *string `json:"status,omitempty"`
Conclusion *string `json:"conclusion,omitempty"`
WorkflowID *int64 `json:"workflow_id,omitempty"`
URL *string `json:"url,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
PullRequests []*PullRequest `json:"pull_requests,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
JobsURL *string `json:"jobs_url,omitempty"`
LogsURL *string `json:"logs_url,omitempty"`
CheckSuiteURL *string `json:"check_suite_url,omitempty"`
ArtifactsURL *string `json:"artifacts_url,omitempty"`
CancelURL *string `json:"cancel_url,omitempty"`
RerunURL *string `json:"rerun_url,omitempty"`
HeadCommit *HeadCommit `json:"head_commit,omitempty"`
WorkflowURL *string `json:"workflow_url,omitempty"`
Repository *Repository `json:"repository,omitempty"`
HeadRepository *Repository `json:"head_repository,omitempty"`
}
// WorkflowRuns represents a slice of repository action workflow run.
type WorkflowRuns struct {
TotalCount *int `json:"total_count,omitempty"`
WorkflowRuns []*WorkflowRun `json:"workflow_runs,omitempty"`
}
// ListWorkflowRunsOptions specifies optional parameters to ListWorkflowRuns.
type ListWorkflowRunsOptions struct {
Actor string `url:"actor,omitempty"`
Branch string `url:"branch,omitempty"`
Event string `url:"event,omitempty"`
Status string `url:"status,omitempty"`
ListOptions
}
// WorkflowRunUsage represents a usage of a specific workflow run.
type WorkflowRunUsage struct {
Billable *WorkflowRunEnvironment `json:"billable,omitempty"`
RunDurationMS *int64 `json:"run_duration_ms,omitempty"`
}
// WorkflowRunEnvironment represents different runner environments available for a workflow run.
type WorkflowRunEnvironment struct {
Ubuntu *WorkflowRunBill `json:"UBUNTU,omitempty"`
MacOS *WorkflowRunBill `json:"MACOS,omitempty"`
Windows *WorkflowRunBill `json:"WINDOWS,omitempty"`
}
// WorkflowRunBill specifies billable time for a specific environment in a workflow run.
type WorkflowRunBill struct {
TotalMS *int64 `json:"total_ms,omitempty"`
Jobs *int `json:"jobs,omitempty"`
}
func (s *ActionsService) listWorkflowRuns(ctx context.Context, endpoint string, opts *ListWorkflowRunsOptions) (*WorkflowRuns, *Response, error) {
u, err := addOptions(endpoint, opts)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
runs := new(WorkflowRuns)
resp, err := s.client.Do(ctx, req, &runs)
if err != nil {
return nil, resp, err
}
return runs, resp, nil
}
// ListWorkflowRunsByID lists all workflow runs by workflow ID.
//
// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#list-workflow-runs
func (s *ActionsService) ListWorkflowRunsByID(ctx context.Context, owner, repo string, workflowID int64, opts *ListWorkflowRunsOptions) (*WorkflowRuns, *Response, error) {
u := fmt.Sprintf("repos/%s/%s/actions/workflows/%v/runs", owner, repo, workflowID)
return s.listWorkflowRuns(ctx, u, opts)
}
// ListWorkflowRunsByFileName lists all workflow runs by workflow file name.
//
// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#list-workflow-runs
func (s *ActionsService) ListWorkflowRunsByFileName(ctx context.Context, owner, repo, workflowFileName string, opts *ListWorkflowRunsOptions) (*WorkflowRuns, *Response, error) {
u := fmt.Sprintf("repos/%s/%s/actions/workflows/%v/runs", owner, repo, workflowFileName)
return s.listWorkflowRuns(ctx, u, opts)
}
// ListRepositoryWorkflowRuns lists all workflow runs for a repository.
//
// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#list-workflow-runs-for-a-repository
func (s *ActionsService) ListRepositoryWorkflowRuns(ctx context.Context, owner, repo string, opts *ListWorkflowRunsOptions) (*WorkflowRuns, *Response, error) {
u := fmt.Sprintf("repos/%s/%s/actions/runs", owner, repo)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
runs := new(WorkflowRuns)
resp, err := s.client.Do(ctx, req, &runs)
if err != nil {
return nil, resp, err
}
return runs, resp, nil
}
// GetWorkflowRunByID gets a specific workflow run by ID.
//
// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#get-a-workflow-run
func (s *ActionsService) GetWorkflowRunByID(ctx context.Context, owner, repo string, runID int64) (*WorkflowRun, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/runs/%v", owner, repo, runID)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
run := new(WorkflowRun)
resp, err := s.client.Do(ctx, req, run)
if err != nil {
return nil, resp, err
}
return run, resp, nil
}
// RerunWorkflow re-runs a workflow by ID.
//
// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#re-run-a-workflow
func (s *ActionsService) RerunWorkflowByID(ctx context.Context, owner, repo string, runID int64) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/rerun", owner, repo, runID)
req, err := s.client.NewRequest("POST", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// CancelWorkflowRunByID cancels a workflow run by ID.
//
// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#cancel-a-workflow-run
func (s *ActionsService) CancelWorkflowRunByID(ctx context.Context, owner, repo string, runID int64) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/cancel", owner, repo, runID)
req, err := s.client.NewRequest("POST", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// GetWorkflowRunLogs gets a redirect URL to download a plain text file of logs for a workflow run.
//
// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#download-workflow-run-logs
func (s *ActionsService) GetWorkflowRunLogs(ctx context.Context, owner, repo string, runID int64, followRedirects bool) (*url.URL, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/logs", owner, repo, runID)
resp, err := s.getWorkflowLogsFromURL(ctx, u, followRedirects)
if err != nil {
return nil, nil, err
}
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
}
// DeleteWorkflowRunLogs deletes all logs for a workflow run.
//
// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#delete-workflow-run-logs
func (s *ActionsService) DeleteWorkflowRunLogs(ctx context.Context, owner, repo string, runID int64) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/logs", owner, repo, runID)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// GetWorkflowRunUsageByID gets a specific workflow usage run by run ID in the unit of billable milliseconds.
//
// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#get-workflow-run-usage
func (s *ActionsService) GetWorkflowRunUsageByID(ctx context.Context, owner, repo string, runID int64) (*WorkflowRunUsage, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/timing", owner, repo, runID)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
workflowRunUsage := new(WorkflowRunUsage)
resp, err := s.client.Do(ctx, req, workflowRunUsage)
if err != nil {
return nil, resp, err
}
return workflowRunUsage, resp, nil
}

View File

@ -0,0 +1,138 @@
// Copyright 2020 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"
)
// Workflow represents a repository action workflow.
type Workflow struct {
ID *int64 `json:"id,omitempty"`
NodeID *string `json:"node_id,omitempty"`
Name *string `json:"name,omitempty"`
Path *string `json:"path,omitempty"`
State *string `json:"state,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
URL *string `json:"url,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
BadgeURL *string `json:"badge_url,omitempty"`
}
// Workflows represents a slice of repository action workflows.
type Workflows struct {
TotalCount *int `json:"total_count,omitempty"`
Workflows []*Workflow `json:"workflows,omitempty"`
}
// WorkflowUsage represents a usage of a specific workflow.
type WorkflowUsage struct {
Billable *WorkflowEnvironment `json:"billable,omitempty"`
}
// WorkflowEnvironment represents different runner environments available for a workflow.
type WorkflowEnvironment struct {
Ubuntu *WorkflowBill `json:"UBUNTU,omitempty"`
MacOS *WorkflowBill `json:"MACOS,omitempty"`
Windows *WorkflowBill `json:"WINDOWS,omitempty"`
}
// WorkflowBill specifies billable time for a specific environment in a workflow.
type WorkflowBill struct {
TotalMS *int64 `json:"total_ms,omitempty"`
}
// ListWorkflows lists all workflows in a repository.
//
// GitHub API docs: https://developer.github.com/v3/actions/workflows/#list-repository-workflows
func (s *ActionsService) ListWorkflows(ctx context.Context, owner, repo string, opts *ListOptions) (*Workflows, *Response, error) {
u := fmt.Sprintf("repos/%s/%s/actions/workflows", owner, repo)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
workflows := new(Workflows)
resp, err := s.client.Do(ctx, req, &workflows)
if err != nil {
return nil, resp, err
}
return workflows, resp, nil
}
// GetWorkflowByID gets a specific workflow by ID.
//
// GitHub API docs: https://developer.github.com/v3/actions/workflows/#get-a-workflow
func (s *ActionsService) GetWorkflowByID(ctx context.Context, owner, repo string, workflowID int64) (*Workflow, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/workflows/%v", owner, repo, workflowID)
return s.getWorkflow(ctx, u)
}
// GetWorkflowByFileName gets a specific workflow by file name.
//
// GitHub API docs: https://developer.github.com/v3/actions/workflows/#get-a-workflow
func (s *ActionsService) GetWorkflowByFileName(ctx context.Context, owner, repo, workflowFileName string) (*Workflow, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/workflows/%v", owner, repo, workflowFileName)
return s.getWorkflow(ctx, u)
}
func (s *ActionsService) getWorkflow(ctx context.Context, url string) (*Workflow, *Response, error) {
req, err := s.client.NewRequest("GET", url, nil)
if err != nil {
return nil, nil, err
}
workflow := new(Workflow)
resp, err := s.client.Do(ctx, req, workflow)
if err != nil {
return nil, resp, err
}
return workflow, resp, nil
}
// GetWorkflowUsageByID gets a specific workflow usage by ID in the unit of billable milliseconds.
//
// GitHub API docs: https://developer.github.com/v3/actions/workflows/#get-workflow-usage
func (s *ActionsService) GetWorkflowUsageByID(ctx context.Context, owner, repo string, workflowID int64) (*WorkflowUsage, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/workflows/%v/timing", owner, repo, workflowID)
return s.getWorkflowUsage(ctx, u)
}
// GetWorkflowUsageByFileName gets a specific workflow usage by file name in the unit of billable milliseconds.
//
// GitHub API docs: https://developer.github.com/v3/actions/workflows/#get-workflow-usage
func (s *ActionsService) GetWorkflowUsageByFileName(ctx context.Context, owner, repo, workflowFileName string) (*WorkflowUsage, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/workflows/%v/timing", owner, repo, workflowFileName)
return s.getWorkflowUsage(ctx, u)
}
func (s *ActionsService) getWorkflowUsage(ctx context.Context, url string) (*WorkflowUsage, *Response, error) {
req, err := s.client.NewRequest("GET", url, nil)
if err != nil {
return nil, nil, err
}
workflowUsage := new(WorkflowUsage)
resp, err := s.client.Do(ctx, req, workflowUsage)
if err != nil {
return nil, resp, err
}
return workflowUsage, resp, nil
}

View File

@ -29,13 +29,13 @@ type Feeds struct {
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"`
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"`
}

View File

@ -13,8 +13,8 @@ import (
// 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)
func (s *ActivityService) ListEvents(ctx context.Context, opts *ListOptions) ([]*Event, *Response, error) {
u, err := addOptions("events", opts)
if err != nil {
return nil, nil, err
}
@ -36,9 +36,9 @@ func (s *ActivityService) ListEvents(ctx context.Context, opt *ListOptions) ([]*
// 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) {
func (s *ActivityService) ListRepositoryEvents(ctx context.Context, owner, repo string, opts *ListOptions) ([]*Event, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/events", owner, repo)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -59,10 +59,10 @@ func (s *ActivityService) ListRepositoryEvents(ctx context.Context, owner, repo
// 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) {
// GitHub API docs: https://developer.github.com/v3/issues/events/#list-issue-events-for-a-repository
func (s *ActivityService) ListIssueEventsForRepository(ctx context.Context, owner, repo string, opts *ListOptions) ([]*IssueEvent, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/events", owner, repo)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -84,9 +84,9 @@ func (s *ActivityService) ListIssueEventsForRepository(ctx context.Context, owne
// 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) {
func (s *ActivityService) ListEventsForRepoNetwork(ctx context.Context, owner, repo string, opts *ListOptions) ([]*Event, *Response, error) {
u := fmt.Sprintf("networks/%v/%v/events", owner, repo)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -107,10 +107,10 @@ func (s *ActivityService) ListEventsForRepoNetwork(ctx context.Context, owner, r
// 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) {
// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-organization-events
func (s *ActivityService) ListEventsForOrganization(ctx context.Context, org string, opts *ListOptions) ([]*Event, *Response, error) {
u := fmt.Sprintf("orgs/%v/events", org)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -132,15 +132,16 @@ func (s *ActivityService) ListEventsForOrganization(ctx context.Context, org str
// 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) {
// GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-for-the-authenticated-user
// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-for-a-user
func (s *ActivityService) ListEventsPerformedByUser(ctx context.Context, user string, publicOnly bool, opts *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)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -162,15 +163,16 @@ func (s *ActivityService) ListEventsPerformedByUser(ctx context.Context, user st
// 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) {
// GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-received-by-the-authenticated-user
// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-received-by-a-user
func (s *ActivityService) ListEventsReceivedByUser(ctx context.Context, user string, publicOnly bool, opts *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)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -192,10 +194,10 @@ func (s *ActivityService) ListEventsReceivedByUser(ctx context.Context, user str
// ListUserEventsForOrganization provides the users 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) {
// GitHub API docs: https://developer.github.com/v3/activity/events/#list-organization-events-for-the-authenticated-user
func (s *ActivityService) ListUserEventsForOrganization(ctx context.Context, org, user string, opts *ListOptions) ([]*Event, *Response, error) {
u := fmt.Sprintf("users/%v/events/orgs/%v", user, org)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}

View File

@ -49,10 +49,10 @@ type NotificationListOptions struct {
// 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) {
// GitHub API docs: https://developer.github.com/v3/activity/notifications/#list-notifications-for-the-authenticated-user
func (s *ActivityService) ListNotifications(ctx context.Context, opts *NotificationListOptions) ([]*Notification, *Response, error) {
u := fmt.Sprintf("notifications")
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -74,10 +74,10 @@ func (s *ActivityService) ListNotifications(ctx context.Context, opt *Notificati
// 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) {
// GitHub API docs: https://developer.github.com/v3/activity/notifications/#list-repository-notifications-for-the-authenticated-user
func (s *ActivityService) ListRepositoryNotifications(ctx context.Context, owner, repo string, opts *NotificationListOptions) ([]*Notification, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/notifications", owner, repo)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -118,7 +118,7 @@ func (s *ActivityService) MarkNotificationsRead(ctx context.Context, lastRead ti
// 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
// GitHub API docs: https://developer.github.com/v3/activity/notifications/#mark-repository-notifications-as-read
func (s *ActivityService) MarkRepositoryNotificationsRead(ctx context.Context, owner, repo string, lastRead time.Time) (*Response, error) {
opts := &markReadOptions{
LastReadAt: lastRead,
@ -134,7 +134,7 @@ func (s *ActivityService) MarkRepositoryNotificationsRead(ctx context.Context, o
// GetThread gets the specified notification thread.
//
// GitHub API docs: https://developer.github.com/v3/activity/notifications/#view-a-single-thread
// GitHub API docs: https://developer.github.com/v3/activity/notifications/#get-a-thread
func (s *ActivityService) GetThread(ctx context.Context, id string) (*Notification, *Response, error) {
u := fmt.Sprintf("notifications/threads/%v", id)
@ -169,7 +169,7 @@ func (s *ActivityService) MarkThreadRead(ctx context.Context, id string) (*Respo
// 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
// GitHub API docs: https://developer.github.com/v3/activity/notifications/#get-a-thread-subscription-for-the-authenticated-user
func (s *ActivityService) GetThreadSubscription(ctx context.Context, id string) (*Subscription, *Response, error) {
u := fmt.Sprintf("notifications/threads/%v/subscription", id)

View File

@ -26,9 +26,9 @@ type Stargazer struct {
// 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) {
func (s *ActivityService) ListStargazers(ctx context.Context, owner, repo string, opts *ListOptions) ([]*Stargazer, *Response, error) {
u := fmt.Sprintf("repos/%s/%s/stargazers", owner, repo)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -67,15 +67,16 @@ type ActivityListStarredOptions struct {
// 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) {
// GitHub API docs: https://developer.github.com/v3/activity/starring/#list-repositories-starred-by-a-user
// GitHub API docs: https://developer.github.com/v3/activity/starring/#list-repositories-starred-by-the-authenticated-user
func (s *ActivityService) ListStarred(ctx context.Context, user string, opts *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)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -100,7 +101,7 @@ func (s *ActivityService) ListStarred(ctx context.Context, user string, opt *Act
// 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
// GitHub API docs: https://developer.github.com/v3/activity/starring/#check-if-a-repository-is-starred-by-the-authenticated-user
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)
@ -114,7 +115,7 @@ func (s *ActivityService) IsStarred(ctx context.Context, owner, repo string) (bo
// Star a repository as the authenticated user.
//
// GitHub API docs: https://developer.github.com/v3/activity/starring/#star-a-repository
// GitHub API docs: https://developer.github.com/v3/activity/starring/#star-a-repository-for-the-authenticated-user
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)
@ -126,7 +127,7 @@ func (s *ActivityService) Star(ctx context.Context, owner, repo string) (*Respon
// Unstar a repository as the authenticated user.
//
// GitHub API docs: https://developer.github.com/v3/activity/starring/#unstar-a-repository
// GitHub API docs: https://developer.github.com/v3/activity/starring/#unstar-a-repository-for-the-authenticated-user
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)

View File

@ -28,9 +28,9 @@ type Subscription struct {
// 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) {
func (s *ActivityService) ListWatchers(ctx context.Context, owner, repo string, opts *ListOptions) ([]*User, *Response, error) {
u := fmt.Sprintf("repos/%s/%s/subscribers", owner, repo)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -52,15 +52,16 @@ func (s *ActivityService) ListWatchers(ctx context.Context, owner, repo string,
// 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) {
// GitHub API docs: https://developer.github.com/v3/activity/watching/#list-repositories-watched-by-a-user
// GitHub API docs: https://developer.github.com/v3/activity/watching/#list-repositories-watched-by-the-authenticated-user
func (s *ActivityService) ListWatched(ctx context.Context, user string, opts *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)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}

View File

@ -62,6 +62,24 @@ func (m UserLDAPMapping) String() string {
return Stringify(m)
}
// Enterprise represents the GitHub enterprise profile.
type Enterprise struct {
ID *int `json:"id,omitempty"`
Slug *string `json:"slug,omitempty"`
Name *string `json:"name,omitempty"`
NodeID *string `json:"node_id,omitempty"`
AvatarURL *string `json:"avatar_url,omitempty"`
Description *string `json:"description,omitempty"`
WebsiteURL *string `json:"website_url,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
}
func (m Enterprise) 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

View File

@ -0,0 +1,89 @@
// 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"
)
// createOrgRequest is a subset of Organization and is used internally
// by CreateOrg to pass only the known fields for the endpoint.
type createOrgRequest struct {
Login *string `json:"login,omitempty"`
Admin *string `json:"admin,omitempty"`
}
// CreateOrg creates a new organization in GitHub Enterprise.
//
// Note that only a subset of the org fields are used and org must
// not be nil.
//
// GitHub Enterprise API docs: https://developer.github.com/enterprise/v3/enterprise-admin/orgs/#create-an-organization
func (s *AdminService) CreateOrg(ctx context.Context, org *Organization, admin string) (*Organization, *Response, error) {
u := "admin/organizations"
orgReq := &createOrgRequest{
Login: org.Login,
Admin: &admin,
}
req, err := s.client.NewRequest("POST", u, orgReq)
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
}
// renameOrgRequest is a subset of Organization and is used internally
// by RenameOrg and RenameOrgByName to pass only the known fields for the endpoint.
type renameOrgRequest struct {
Login *string `json:"login,omitempty"`
}
// RenameOrgResponse is the response given when renaming an Organization.
type RenameOrgResponse struct {
Message *string `json:"message,omitempty"`
URL *string `json:"url,omitempty"`
}
// RenameOrg renames an organization in GitHub Enterprise.
//
// GitHub Enterprise API docs: https://developer.github.com/enterprise/v3/enterprise-admin/orgs/#rename-an-organization
func (s *AdminService) RenameOrg(ctx context.Context, org *Organization, newName string) (*RenameOrgResponse, *Response, error) {
return s.RenameOrgByName(ctx, *org.Login, newName)
}
// RenameOrgByName renames an organization in GitHub Enterprise using its current name.
//
// GitHub Enterprise API docs: https://developer.github.com/enterprise/v3/enterprise-admin/orgs/#rename-an-organization
func (s *AdminService) RenameOrgByName(ctx context.Context, org, newName string) (*RenameOrgResponse, *Response, error) {
u := fmt.Sprintf("admin/organizations/%v", org)
orgReq := &renameOrgRequest{
Login: &newName,
}
req, err := s.client.NewRequest("PATCH", u, orgReq)
if err != nil {
return nil, nil, err
}
o := new(RenameOrgResponse)
resp, err := s.client.Do(ctx, req, o)
if err != nil {
return nil, resp, err
}
return o, resp, nil
}

View File

@ -10,7 +10,7 @@ import (
"fmt"
)
// AdminStats represents a variety of stats of a Github Enterprise
// AdminStats represents a variety of stats of a GitHub Enterprise
// installation.
type AdminStats struct {
Issues *IssueStats `json:"issues,omitempty"`
@ -147,7 +147,7 @@ func (s RepoStats) String() string {
return Stringify(s)
}
// GetAdminStats returns a variety of metrics about a Github Enterprise
// GetAdminStats returns a variety of metrics about a GitHub Enterprise
// installation.
//
// Please note that this is only available to site administrators,

View File

@ -0,0 +1,133 @@
// 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"
)
// createUserRequest is a subset of User and is used internally
// by CreateUser to pass only the known fields for the endpoint.
type createUserRequest struct {
Login *string `json:"login,omitempty"`
Email *string `json:"email,omitempty"`
}
// CreateUser creates a new user in GitHub Enterprise.
//
// GitHub Enterprise API docs: https://developer.github.com/enterprise/v3/enterprise-admin/users/#create-a-new-user
func (s *AdminService) CreateUser(ctx context.Context, login, email string) (*User, *Response, error) {
u := "admin/users"
userReq := &createUserRequest{
Login: &login,
Email: &email,
}
req, err := s.client.NewRequest("POST", u, userReq)
if err != nil {
return nil, nil, err
}
var user User
resp, err := s.client.Do(ctx, req, &user)
if err != nil {
return nil, resp, err
}
return &user, resp, nil
}
// DeleteUser deletes a user in GitHub Enterprise.
//
// GitHub Enterprise API docs: https://developer.github.com/enterprise/v3/enterprise-admin/users/#delete-a-user
func (s *AdminService) DeleteUser(ctx context.Context, username string) (*Response, error) {
u := "admin/users/" + username
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
resp, err := s.client.Do(ctx, req, nil)
if err != nil {
return resp, err
}
return resp, nil
}
// ImpersonateUserOptions represents the scoping for the OAuth token.
type ImpersonateUserOptions struct {
Scopes []string `json:"scopes,omitempty"`
}
// OAuthAPP represents the GitHub Site Administrator OAuth app.
type OAuthAPP struct {
URL *string `json:"url,omitempty"`
Name *string `json:"name,omitempty"`
ClientID *string `json:"client_id,omitempty"`
}
func (s OAuthAPP) String() string {
return Stringify(s)
}
// UserAuthorization represents the impersonation response.
type UserAuthorization struct {
ID *int64 `json:"id,omitempty"`
URL *string `json:"url,omitempty"`
Scopes []string `json:"scopes,omitempty"`
Token *string `json:"token,omitempty"`
TokenLastEight *string `json:"token_last_eight,omitempty"`
HashedToken *string `json:"hashed_token,omitempty"`
App *OAuthAPP `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"`
}
// CreateUserImpersonation creates an impersonation OAuth token.
//
// GitHub Enterprise API docs: https://developer.github.com/enterprise/v3/enterprise-admin/users/#create-an-impersonation-oauth-token
func (s *AdminService) CreateUserImpersonation(ctx context.Context, username string, opts *ImpersonateUserOptions) (*UserAuthorization, *Response, error) {
u := fmt.Sprintf("admin/users/%s/authorizations", username)
req, err := s.client.NewRequest("POST", u, opts)
if err != nil {
return nil, nil, err
}
a := new(UserAuthorization)
resp, err := s.client.Do(ctx, req, a)
if err != nil {
return nil, resp, err
}
return a, resp, nil
}
// DeleteUserImpersonation deletes an impersonation OAuth token.
//
// GitHub Enterprise API docs: https://developer.github.com/enterprise/v3/enterprise-admin/users/#delete-an-impersonation-oauth-token
func (s *AdminService) DeleteUserImpersonation(ctx context.Context, username string) (*Response, error) {
u := fmt.Sprintf("admin/users/%s/authorizations", username)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
resp, err := s.client.Do(ctx, req, nil)
if err != nil {
return resp, err
}
return resp, nil
}

349
vendor/github.com/google/go-github/v32/github/apps.go generated vendored Normal file
View File

@ -0,0 +1,349 @@
// 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"`
Slug *string `json:"slug,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 *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
Permissions *InstallationPermissions `json:"permissions,omitempty"`
Events []string `json:"events,omitempty"`
}
// InstallationToken represents an installation token.
type InstallationToken struct {
Token *string `json:"token,omitempty"`
ExpiresAt *time.Time `json:"expires_at,omitempty"`
Permissions *InstallationPermissions `json:"permissions,omitempty"`
Repositories []*Repository `json:"repositories,omitempty"`
}
// InstallationTokenOptions allow restricting a token's access to specific repositories.
type InstallationTokenOptions struct {
// The IDs of the repositories that the installation token can access.
// Providing repository IDs restricts the access of an installation token to specific repositories.
RepositoryIDs []int64 `json:"repository_ids,omitempty"`
// The permissions granted to the access token.
// The permissions object includes the permission names and their access type.
Permissions *InstallationPermissions `json:"permissions,omitempty"`
}
// InstallationPermissions lists the repository and organization permissions for an installation.
//
// Permission names taken from:
// https://developer.github.com/v3/apps/permissions/
// https://developer.github.com/enterprise/v3/apps/permissions/
type InstallationPermissions struct {
Administration *string `json:"administration,omitempty"`
Blocking *string `json:"blocking,omitempty"`
Checks *string `json:"checks,omitempty"`
Contents *string `json:"contents,omitempty"`
ContentReferences *string `json:"content_references,omitempty"`
Deployments *string `json:"deployments,omitempty"`
Emails *string `json:"emails,omitempty"`
Followers *string `json:"followers,omitempty"`
Issues *string `json:"issues,omitempty"`
Metadata *string `json:"metadata,omitempty"`
Members *string `json:"members,omitempty"`
OrganizationAdministration *string `json:"organization_administration,omitempty"`
OrganizationHooks *string `json:"organization_hooks,omitempty"`
OrganizationPlan *string `json:"organization_plan,omitempty"`
OrganizationPreReceiveHooks *string `json:"organization_pre_receive_hooks,omitempty"`
OrganizationProjects *string `json:"organization_projects,omitempty"`
OrganizationUserBlocking *string `json:"organization_user_blocking,omitempty"`
Packages *string `json:"packages,omitempty"`
Pages *string `json:"pages,omitempty"`
PullRequests *string `json:"pull_requests,omitempty"`
RepositoryHooks *string `json:"repository_hooks,omitempty"`
RepositoryProjects *string `json:"repository_projects,omitempty"`
RepositoryPreReceiveHooks *string `json:"repository_pre_receive_hooks,omitempty"`
SingleFile *string `json:"single_file,omitempty"`
Statuses *string `json:"statuses,omitempty"`
TeamDiscussions *string `json:"team_discussions,omitempty"`
VulnerabilityAlerts *string `json:"vulnerability_alerts,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"`
}
// Attachment represents a GitHub Apps attachment.
type Attachment struct {
ID *int64 `json:"id,omitempty"`
Title *string `json:"title,omitempty"`
Body *string `json:"body,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-the-authenticated-app
// GitHub API docs: https://developer.github.com/v3/apps/#get-an-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/#list-installations-for-the-authenticated-app
func (s *AppsService) ListInstallations(ctx context.Context, opts *ListOptions) ([]*Installation, *Response, error) {
u, err := addOptions("app/installations", opts)
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-an-installation-for-the-authenticated-app
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/installations/#list-app-installations-accessible-to-the-user-access-token
func (s *AppsService) ListUserInstallations(ctx context.Context, opts *ListOptions) ([]*Installation, *Response, error) {
u, err := addOptions("user/installations", opts)
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
}
// SuspendInstallation suspends the specified installation.
//
// GitHub API docs: https://developer.github.com/v3/apps/#suspend-an-app-installation
func (s *AppsService) SuspendInstallation(ctx context.Context, id int64) (*Response, error) {
u := fmt.Sprintf("app/installations/%v/suspended", id)
req, err := s.client.NewRequest("PUT", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// UnsuspendInstallation unsuspends the specified installation.
//
// GitHub API docs: https://developer.github.com/v3/apps/#unsuspend-an-app-installation
func (s *AppsService) UnsuspendInstallation(ctx context.Context, id int64) (*Response, error) {
u := fmt.Sprintf("app/installations/%v/suspended", id)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// DeleteInstallation deletes the specified installation.
//
// GitHub API docs: https://developer.github.com/v3/apps/#delete-an-installation-for-the-authenticated-app
func (s *AppsService) DeleteInstallation(ctx context.Context, id int64) (*Response, error) {
u := fmt.Sprintf("app/installations/%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", mediaTypeIntegrationPreview)
return s.client.Do(ctx, req, nil)
}
// CreateInstallationToken creates a new installation token.
//
// GitHub API docs: https://developer.github.com/v3/apps/#create-an-installation-access-token-for-an-app
func (s *AppsService) CreateInstallationToken(ctx context.Context, id int64, opts *InstallationTokenOptions) (*InstallationToken, *Response, error) {
u := fmt.Sprintf("app/installations/%v/access_tokens", id)
req, err := s.client.NewRequest("POST", u, opts)
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
}
// CreateAttachment creates a new attachment on user comment containing a url.
//
// GitHub API docs: https://developer.github.com/v3/apps/installations/#create-a-content-attachment
func (s *AppsService) CreateAttachment(ctx context.Context, contentReferenceID int64, title, body string) (*Attachment, *Response, error) {
u := fmt.Sprintf("content_references/%v/attachments", contentReferenceID)
payload := &Attachment{Title: String(title), Body: String(body)}
req, err := s.client.NewRequest("POST", u, payload)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept headers when APIs fully launch.
req.Header.Set("Accept", mediaTypeReactionsPreview)
m := &Attachment{}
resp, err := s.client.Do(ctx, req, m)
if err != nil {
return nil, resp, err
}
return m, resp, nil
}
// FindOrganizationInstallation finds the organization's installation information.
//
// GitHub API docs: https://developer.github.com/v3/apps/#get-an-organization-installation-for-the-authenticated-app
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/#get-a-repository-installation-for-the-authenticated-app
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/#get-a-user-installation-for-the-authenticated-app
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
}

View File

@ -12,9 +12,9 @@ import (
// 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)
// GitHub API docs: https://developer.github.com/v3/apps/installations/#list-repositories-accessible-to-the-app-installation
func (s *AppsService) ListRepos(ctx context.Context, opts *ListOptions) ([]*Repository, *Response, error) {
u, err := addOptions("installation/repositories", opts)
if err != nil {
return nil, nil, err
}
@ -41,10 +41,10 @@ func (s *AppsService) ListRepos(ctx context.Context, opt *ListOptions) ([]*Repos
// 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) {
// GitHub API docs: https://developer.github.com/v3/apps/installations/#list-repositories-accessible-to-the-user-access-token
func (s *AppsService) ListUserRepos(ctx context.Context, id int64, opts *ListOptions) ([]*Repository, *Response, error) {
u := fmt.Sprintf("user/installations/%v/repositories", id)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -70,7 +70,7 @@ func (s *AppsService) ListUserRepos(ctx context.Context, id int64, opt *ListOpti
// AddRepository adds a single repository to an installation.
//
// GitHub API docs: https://developer.github.com/v3/apps/installations/#add-repository-to-installation
// GitHub API docs: https://developer.github.com/v3/apps/installations/#add-a-repository-to-an-app-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)
@ -90,7 +90,7 @@ func (s *AppsService) AddRepository(ctx context.Context, instID, repoID int64) (
// RemoveRepository removes a single repository from an installation.
//
// GitHub docs: https://developer.github.com/v3/apps/installations/#remove-repository-from-installation
// GitHub API docs: https://developer.github.com/v3/apps/installations/#remove-a-repository-from-an-app-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)
@ -101,3 +101,16 @@ func (s *AppsService) RemoveRepository(ctx context.Context, instID, repoID int64
return s.client.Do(ctx, req, nil)
}
// RevokeInstallationToken revokes an installation token.
//
// GitHub API docs: https://developer.github.com/v3/apps/installations/#revoke-an-installation-access-token
func (s *AppsService) RevokeInstallationToken(ctx context.Context) (*Response, error) {
u := "installation/token"
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}

View File

@ -0,0 +1,53 @@
// 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"
)
const (
mediaTypeAppManifestPreview = "application/vnd.github.fury-preview+json"
)
// AppConfig describes the configuration of a GitHub App.
type AppConfig 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 *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
ClientID *string `json:"client_id,omitempty"`
ClientSecret *string `json:"client_secret,omitempty"`
WebhookSecret *string `json:"webhook_secret,omitempty"`
PEM *string `json:"pem,omitempty"`
}
// CompleteAppManifest completes the App manifest handshake flow for the given
// code.
//
// GitHub API docs: https://developer.github.com/v3/apps/#create-a-github-app-from-a-manifest
func (s *AppsService) CompleteAppManifest(ctx context.Context, code string) (*AppConfig, *Response, error) {
u := fmt.Sprintf("app-manifests/%s/conversions", code)
req, err := s.client.NewRequest("POST", u, nil)
if err != nil {
return nil, nil, err
}
req.Header.Set("Accept", mediaTypeAppManifestPreview)
cfg := new(AppConfig)
resp, err := s.client.Do(ctx, req, cfg)
if err != nil {
return nil, resp, err
}
return cfg, resp, nil
}

View File

@ -68,6 +68,7 @@ type MarketplacePlanAccount struct {
URL *string `json:"url,omitempty"`
Type *string `json:"type,omitempty"`
ID *int64 `json:"id,omitempty"`
NodeID *string `json:"node_id,omitempty"`
Login *string `json:"login,omitempty"`
Email *string `json:"email,omitempty"`
OrganizationBillingEmail *string `json:"organization_billing_email,omitempty"`
@ -78,9 +79,9 @@ type MarketplacePlanAccount struct {
// 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) {
func (s *MarketplaceService) ListPlans(ctx context.Context, opts *ListOptions) ([]*MarketplacePlan, *Response, error) {
uri := s.marketplaceURI("plans")
u, err := addOptions(uri, opt)
u, err := addOptions(uri, opts)
if err != nil {
return nil, nil, err
}
@ -102,9 +103,9 @@ func (s *MarketplaceService) ListPlans(ctx context.Context, opt *ListOptions) ([
// 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) {
func (s *MarketplaceService) ListPlanAccountsForPlan(ctx context.Context, planID int64, opts *ListOptions) ([]*MarketplacePlanAccount, *Response, error) {
uri := s.marketplaceURI(fmt.Sprintf("plans/%v/accounts", planID))
u, err := addOptions(uri, opt)
u, err := addOptions(uri, opts)
if err != nil {
return nil, nil, err
}
@ -126,9 +127,9 @@ func (s *MarketplaceService) ListPlanAccountsForPlan(ctx context.Context, planID
// 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) {
func (s *MarketplaceService) ListPlanAccountsForAccount(ctx context.Context, accountID int64, opts *ListOptions) ([]*MarketplacePlanAccount, *Response, error) {
uri := s.marketplaceURI(fmt.Sprintf("accounts/%v", accountID))
u, err := addOptions(uri, opt)
u, err := addOptions(uri, opts)
if err != nil {
return nil, nil, err
}
@ -149,14 +150,15 @@ func (s *MarketplaceService) ListPlanAccountsForAccount(ctx context.Context, acc
// 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) {
// GitHub API docs: https://developer.github.com/v3/apps/marketplace/#list-subscriptions-for-the-authenticated-user
// GitHub API docs: https://developer.github.com/v3/apps/marketplace/#list-subscriptions-for-the-authenticated-user-stubbed
func (s *MarketplaceService) ListMarketplacePurchasesForUser(ctx context.Context, opts *ListOptions) ([]*MarketplacePurchase, *Response, error) {
uri := "user/marketplace_purchases"
if s.Stubbed {
uri = "user/marketplace_purchases/stubbed"
}
u, err := addOptions(uri, opt)
u, err := addOptions(uri, opts)
if err != nil {
return nil, nil, err
}

View File

@ -41,6 +41,7 @@ const (
ScopeReadGPGKey Scope = "read:gpg_key"
ScopeWriteGPGKey Scope = "write:gpg_key"
ScopeAdminGPGKey Scope = "admin:gpg_key"
ScopeSecurityEvents Scope = "security_events"
)
// AuthorizationsService handles communication with the authorization related
@ -134,137 +135,6 @@ 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 doesnt 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
@ -273,14 +143,19 @@ func (s *AuthorizationsService) Delete(ctx context.Context, id int64) (*Response
//
// 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)
// GitHub API docs: https://developer.github.com/v3/apps/oauth_applications/#check-a-token
func (s *AuthorizationsService) Check(ctx context.Context, clientID, accessToken string) (*Authorization, *Response, error) {
u := fmt.Sprintf("applications/%v/token", clientID)
req, err := s.client.NewRequest("GET", u, nil)
reqBody := &struct {
AccessToken string `json:"access_token"`
}{AccessToken: accessToken}
req, err := s.client.NewRequest("POST", u, reqBody)
if err != nil {
return nil, nil, err
}
req.Header.Set("Accept", mediaTypeOAuthAppPreview)
a := new(Authorization)
resp, err := s.client.Do(ctx, req, a)
@ -301,14 +176,19 @@ func (s *AuthorizationsService) Check(ctx context.Context, clientID string, toke
//
// 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)
// GitHub API docs: https://developer.github.com/v3/apps/oauth_applications/#reset-a-token
func (s *AuthorizationsService) Reset(ctx context.Context, clientID, accessToken string) (*Authorization, *Response, error) {
u := fmt.Sprintf("applications/%v/token", clientID)
req, err := s.client.NewRequest("POST", u, nil)
reqBody := &struct {
AccessToken string `json:"access_token"`
}{AccessToken: accessToken}
req, err := s.client.NewRequest("PATCH", u, reqBody)
if err != nil {
return nil, nil, err
}
req.Header.Set("Accept", mediaTypeOAuthAppPreview)
a := new(Authorization)
resp, err := s.client.Do(ctx, req, a)
@ -325,74 +205,40 @@ func (s *AuthorizationsService) Reset(ctx context.Context, clientID string, toke
// 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)
// GitHub API docs: https://developer.github.com/v3/apps/oauth_applications/#delete-an-app-token
func (s *AuthorizationsService) Revoke(ctx context.Context, clientID, accessToken string) (*Response, error) {
u := fmt.Sprintf("applications/%v/token", clientID)
req, err := s.client.NewRequest("DELETE", u, nil)
reqBody := &struct {
AccessToken string `json:"access_token"`
}{AccessToken: accessToken}
req, err := s.client.NewRequest("DELETE", u, reqBody)
if err != nil {
return nil, err
}
req.Header.Set("Accept", mediaTypeOAuthAppPreview)
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)
// GitHub API docs: https://developer.github.com/v3/apps/oauth_applications/#delete-an-app-authorization
func (s *AuthorizationsService) DeleteGrant(ctx context.Context, clientID, accessToken string) (*Response, error) {
u := fmt.Sprintf("applications/%v/grant", clientID)
reqBody := &struct {
AccessToken string `json:"access_token"`
}{AccessToken: accessToken}
req, err := s.client.NewRequest("DELETE", u, reqBody)
if err != nil {
return nil, err
}
req.Header.Set("Accept", mediaTypeOAuthAppPreview)
return s.client.Do(ctx, req, nil)
}

View File

@ -8,7 +8,6 @@ package github
import (
"context"
"fmt"
"net/url"
)
// ChecksService provides access to the Checks API in the
@ -51,9 +50,10 @@ type CheckRunOutput struct {
// 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"`
StartColumn *int `json:"start_column,omitempty"`
EndColumn *int `json:"end_column,omitempty"`
AnnotationLevel *string `json:"annotation_level,omitempty"`
Message *string `json:"message,omitempty"`
Title *string `json:"title,omitempty"`
@ -81,6 +81,9 @@ type CheckSuite struct {
App *App `json:"app,omitempty"`
Repository *Repository `json:"repository,omitempty"`
PullRequests []*PullRequest `json:"pull_requests,omitempty"`
// The following fields are only populated by Webhook events.
HeadCommit *Commit `json:"head_commit,omitempty"`
}
func (c CheckRun) String() string {
@ -93,7 +96,7 @@ func (c CheckSuite) String() string {
// GetCheckRun gets a check-run for a repository.
//
// GitHub API docs: https://developer.github.com/v3/checks/runs/#get-a-single-check-run
// GitHub API docs: https://developer.github.com/v3/checks/runs/#get-a-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)
@ -114,7 +117,7 @@ func (s *ChecksService) GetCheckRun(ctx context.Context, owner, repo string, che
// GetCheckSuite gets a single check suite.
//
// GitHub API docs: https://developer.github.com/v3/checks/suites/#get-a-single-check-suite
// GitHub API docs: https://developer.github.com/v3/checks/suites/#get-a-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)
@ -136,12 +139,11 @@ func (s *ChecksService) GetCheckSuite(ctx context.Context, owner, repo string, c
// 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".)
Conclusion *string `json:"conclusion,omitempty"` // Can be one of "success", "failure", "neutral", "cancelled", "skipped", "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)
@ -158,9 +160,9 @@ type CheckRunAction struct {
// 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) {
func (s *ChecksService) CreateCheckRun(ctx context.Context, owner, repo string, opts CreateCheckRunOptions) (*CheckRun, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/check-runs", owner, repo)
req, err := s.client.NewRequest("POST", u, opt)
req, err := s.client.NewRequest("POST", u, opts)
if err != nil {
return nil, nil, err
}
@ -179,12 +181,11 @@ func (s *ChecksService) CreateCheckRun(ctx context.Context, owner, repo string,
// 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".)
Conclusion *string `json:"conclusion,omitempty"` // Can be one of "success", "failure", "neutral", "cancelled", "skipped", "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.)
@ -193,9 +194,9 @@ type UpdateCheckRunOptions struct {
// 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) {
func (s *ChecksService) UpdateCheckRun(ctx context.Context, owner, repo string, checkRunID int64, opts UpdateCheckRunOptions) (*CheckRun, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/check-runs/%v", owner, repo, checkRunID)
req, err := s.client.NewRequest("PATCH", u, opt)
req, err := s.client.NewRequest("PATCH", u, opts)
if err != nil {
return nil, nil, err
}
@ -213,10 +214,10 @@ func (s *ChecksService) UpdateCheckRun(ctx context.Context, owner, repo string,
// 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) {
// GitHub API docs: https://developer.github.com/v3/checks/runs/#list-check-run-annotations
func (s *ChecksService) ListCheckRunAnnotations(ctx context.Context, owner, repo string, checkRunID int64, opts *ListOptions) ([]*CheckRunAnnotation, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/check-runs/%v/annotations", owner, repo, checkRunID)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -254,10 +255,10 @@ type ListCheckRunsResults struct {
// 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)
// GitHub API docs: https://developer.github.com/v3/checks/runs/#list-check-runs-for-a-git-reference
func (s *ChecksService) ListCheckRunsForRef(ctx context.Context, owner, repo, ref string, opts *ListCheckRunsOptions) (*ListCheckRunsResults, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/commits/%v/check-runs", owner, repo, refURLEscape(ref))
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -281,9 +282,9 @@ func (s *ChecksService) ListCheckRunsForRef(ctx context.Context, owner, repo, re
// 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) {
func (s *ChecksService) ListCheckRunsCheckSuite(ctx context.Context, owner, repo string, checkSuiteID int64, opts *ListCheckRunsOptions) (*ListCheckRunsResults, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/check-suites/%v/check-runs", owner, repo, checkSuiteID)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -320,10 +321,10 @@ type ListCheckSuiteResults struct {
// 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)
// GitHub API docs: https://developer.github.com/v3/checks/suites/#list-check-suites-for-a-git-reference
func (s *ChecksService) ListCheckSuitesForRef(ctx context.Context, owner, repo, ref string, opts *ListCheckSuiteOptions) (*ListCheckSuiteResults, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/commits/%v/check-suites", owner, repo, refURLEscape(ref))
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -352,7 +353,7 @@ type AutoTriggerCheck struct {
// 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.
AutoTriggerChecks []*AutoTriggerCheck `json:"auto_trigger_checks,omitempty"` // A slice of auto trigger checks that can be set for a check suite in a repository.
}
// CheckSuitePreferenceResults represents the results of the preference set operation.
@ -361,17 +362,17 @@ type CheckSuitePreferenceResults struct {
Repository *Repository `json:"repository,omitempty"`
}
// PreferenceList represents a list of auto trigger checks for repository
// 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) {
// GitHub API docs: https://developer.github.com/v3/checks/suites/#update-repository-preferences-for-check-suites
func (s *ChecksService) SetCheckSuitePreferences(ctx context.Context, owner, repo string, opts CheckSuitePreferenceOptions) (*CheckSuitePreferenceResults, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/check-suites/preferences", owner, repo)
req, err := s.client.NewRequest("PATCH", u, opt)
req, err := s.client.NewRequest("PATCH", u, opts)
if err != nil {
return nil, nil, err
}
@ -396,9 +397,9 @@ type CreateCheckSuiteOptions struct {
// 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) {
func (s *ChecksService) CreateCheckSuite(ctx context.Context, owner, repo string, opts CreateCheckSuiteOptions) (*CheckSuite, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/check-suites", owner, repo)
req, err := s.client.NewRequest("POST", u, opt)
req, err := s.client.NewRequest("POST", u, opts)
if err != nil {
return nil, nil, err
}
@ -416,7 +417,7 @@ func (s *ChecksService) CreateCheckSuite(ctx context.Context, owner, repo string
// 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
// GitHub API docs: https://developer.github.com/v3/checks/suites/#rerequest-a-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)

View File

@ -0,0 +1,117 @@
// Copyright 2020 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"
"strings"
)
// CodeScanningService handles communication with the code scanning related
// methods of the GitHub API.
//
// GitHub API docs: https://developer.github.com/v3/code-scanning/
type CodeScanningService service
type Alert struct {
RuleID *string `json:"rule_id,omitempty"`
RuleSeverity *string `json:"rule_severity,omitempty"`
RuleDescription *string `json:"rule_description,omitempty"`
Tool *string `json:"tool,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
Open *bool `json:"open,omitempty"`
ClosedBy *User `json:"closed_by,omitempty"`
ClosedAt *Timestamp `json:"closed_at,omitempty"`
URL *string `json:"url,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
}
// ID returns the ID associated with an alert. It is the number at the end of the security alert's URL.
func (a *Alert) ID() int64 {
if a == nil {
return 0
}
s := a.GetHTMLURL()
// Check for an ID to parse at the end of the url
if i := strings.LastIndex(s, "/"); i >= 0 {
s = s[i+1:]
}
// Return the alert ID as a 64-bit integer. Unable to convert or out of range returns 0.
id, err := strconv.ParseInt(s, 10, 64)
if err != nil {
return 0
}
return id
}
// AlertListOptions specifies optional parameters to the CodeScanningService.ListAlerts
// method.
type AlertListOptions struct {
// State of the code scanning alerts to list. Set to closed to list only closed code scanning alerts. Default: open
State string `url:"state,omitempty"`
// Return code scanning alerts for a specific branch reference. The ref must be formatted as heads/<branch name>.
Ref string `url:"ref,omitempty"`
}
// ListAlertsForRepo lists code scanning alerts for a repository.
//
// Lists all open code scanning alerts for the default branch (usually master) and protected branches in a repository.
// You must use an access token with the security_events scope to use this endpoint. GitHub Apps must have the security_events
// read permission to use this endpoint.
//
// GitHub API docs: https://developer.github.com/v3/code-scanning/#list-code-scanning-alerts-for-a-repository
func (s *CodeScanningService) ListAlertsForRepo(ctx context.Context, owner, repo string, opts *AlertListOptions) ([]*Alert, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/code-scanning/alerts", owner, repo)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
var alerts []*Alert
resp, err := s.client.Do(ctx, req, &alerts)
if err != nil {
return nil, resp, err
}
return alerts, resp, nil
}
// GetAlert gets a single code scanning alert for a repository.
//
// You must use an access token with the security_events scope to use this endpoint.
// GitHub Apps must have the security_events read permission to use this endpoint.
//
// The security alert_id is the number at the end of the security alert's URL.
//
// GitHub API docs: https://developer.github.com/v3/code-scanning/#get-a-code-scanning-alert
func (s *CodeScanningService) GetAlert(ctx context.Context, owner, repo string, id int64) (*Alert, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/code-scanning/alerts/%v", owner, repo, id)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
a := new(Alert)
resp, err := s.client.Do(ctx, req, a)
if err != nil {
return nil, resp, err
}
return a, resp, nil
}

View File

@ -8,7 +8,7 @@ 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/v32/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

View File

@ -40,6 +40,8 @@ func (e *Event) ParsePayload() (payload interface{}, err error) {
payload = &CreateEvent{}
case "DeleteEvent":
payload = &DeleteEvent{}
case "DeployKeyEvent":
payload = &DeployKeyEvent{}
case "DeploymentEvent":
payload = &DeploymentEvent{}
case "DeploymentStatusEvent":
@ -66,12 +68,16 @@ func (e *Event) ParsePayload() (payload interface{}, err error) {
payload = &MemberEvent{}
case "MembershipEvent":
payload = &MembershipEvent{}
case "MetaEvent":
payload = &MetaEvent{}
case "MilestoneEvent":
payload = &MilestoneEvent{}
case "OrganizationEvent":
payload = &OrganizationEvent{}
case "OrgBlockEvent":
payload = &OrgBlockEvent{}
case "PackageEvent":
payload = &PackageEvent{}
case "PageBuildEvent":
payload = &PageBuildEvent{}
case "PingEvent":
@ -96,14 +102,20 @@ func (e *Event) ParsePayload() (payload interface{}, err error) {
payload = &ReleaseEvent{}
case "RepositoryEvent":
payload = &RepositoryEvent{}
case "RepositoryDispatchEvent":
payload = &RepositoryDispatchEvent{}
case "RepositoryVulnerabilityAlertEvent":
payload = &RepositoryVulnerabilityAlertEvent{}
case "StarEvent":
payload = &StarEvent{}
case "StatusEvent":
payload = &StatusEvent{}
case "TeamEvent":
payload = &TeamEvent{}
case "TeamAddEvent":
payload = &TeamAddEvent{}
case "UserEvent":
payload = &UserEvent{}
case "WatchEvent":
payload = &WatchEvent{}
}

View File

@ -7,19 +7,21 @@
package github
import "encoding/json"
// 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".
// CheckRunEvent is triggered when a check run is "created", "updated", or "rerequested".
// 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".
// The action performed. Possible values are: "created", "updated", "rerequested" or "requested_action".
Action *string `json:"action,omitempty"`
// The following fields are only populated by Webhook events.
@ -32,13 +34,13 @@ type CheckRunEvent struct {
RequestedAction *RequestedAction `json:"requested_action,omitempty"` //
}
// CheckSuiteEvent is triggered when a check suite is "completed", "requested", or "re-requested".
// CheckSuiteEvent is triggered when a check suite is "completed", "requested", or "rerequested".
// 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".
// The action performed. Possible values are: "completed", "requested" or "rerequested".
Action *string `json:"action,omitempty"`
// The following fields are only populated by Webhook events.
@ -103,6 +105,19 @@ type DeleteEvent struct {
Installation *Installation `json:"installation,omitempty"`
}
// DeployKeyEvent is triggered when a deploy key is added or removed from a repository.
// The Webhook event name is "deploy_key".
//
// GitHub API docs: https://developer.github.com/v3/activity/events/types/#deploykeyevent
type DeployKeyEvent struct {
// Action is the action that was performed. Possible values are:
// "created" or "deleted".
Action *string `json:"action,omitempty"`
// The deploy key resource.
Key *Key `json:"key,omitempty"`
}
// DeploymentEvent represents a deployment.
// The Webhook event name is "deployment".
//
@ -153,7 +168,7 @@ type ForkEvent struct {
//
// GitHub API docs: https://developer.github.com/v3/activity/events/types/#githubappauthorizationevent
type GitHubAppAuthorizationEvent struct {
// The action performed. Can be "revoked".
// The action performed. Possible value is: "revoked".
Action *string `json:"action,omitempty"`
// The following fields are only populated by Webhook events.
@ -285,14 +300,17 @@ type IssueCommentEvent struct {
Installation *Installation `json:"installation,omitempty"`
}
// IssuesEvent is triggered when an issue is assigned, unassigned, labeled,
// unlabeled, opened, closed, or reopened.
// IssuesEvent is triggered when an issue is opened, edited, deleted, transferred,
// pinned, unpinned, closed, reopened, assigned, unassigned, labeled, unlabeled,
// locked, unlocked, milestoned, or demilestoned.
// 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 is the action that was performed. Possible values are: "opened",
// "edited", "deleted", "transferred", "pinned", "unpinned", "closed", "reopened",
// "assigned", "unassigned", "labeled", "unlabeled", "locked", "unlocked",
// "milestoned", or "demilestoned".
Action *string `json:"action,omitempty"`
Issue *Issue `json:"issue,omitempty"`
Assignee *User `json:"assignee,omitempty"`
@ -376,6 +394,23 @@ type MembershipEvent struct {
Installation *Installation `json:"installation,omitempty"`
}
// MetaEvent is triggered when the webhook that this event is configured on is deleted.
// This event will only listen for changes to the particular hook the event is installed on.
// Therefore, it must be selected for each hook that you'd like to receive meta events for.
// The Webhook event name is "meta".
//
// GitHub API docs: https://developer.github.com/v3/activity/events/types/#metaevent
type MetaEvent struct {
// Action is the action that was performed. Possible value is: "deleted".
Action *string `json:"action,omitempty"`
// The ID of the modified webhook.
HookID *int64 `json:"hook_id,omitempty"`
// The modified webhook.
// This will contain different keys based on the type of webhook it is: repository,
// organization, business, app, or GitHub Marketplace.
Hook *Hook `json:"hook,omitempty"`
}
// MilestoneEvent is triggered when a milestone is created, closed, opened, edited, or deleted.
// The Webhook event name is "milestone".
//
@ -394,17 +429,18 @@ type MilestoneEvent struct {
Installation *Installation `json:"installation,omitempty"`
}
// OrganizationEvent is triggered when a user is added, removed, or invited to an organization.
// OrganizationEvent is triggered when an organization is deleted and renamed, and 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".
// Possible values are: "deleted", "renamed", "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 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.
@ -432,6 +468,22 @@ type OrgBlockEvent struct {
Installation *Installation `json:"installation,omitempty"`
}
// PackageEvent represents activity related to GitHub Packages.
// The Webhook event name is "package".
//
// This event is triggered when a GitHub Package is published or updated.
//
// GitHub API docs: https://developer.github.com/webhooks/event-payloads/#package
type PackageEvent struct {
// Action is the action that was performed.
// Can be "published" or "updated".
Action *string `json:"action,omitempty"`
Package *Package `json:"package,omitempty"`
Repo *Repository `json:"repository,omitempty"`
Org *Organization `json:"organization,omitempty"`
Sender *User `json:"sender,omitempty"`
}
// PageBuildEvent represents an attempted build of a GitHub Pages site, whether
// successful or not.
// The Webhook event name is "page_build".
@ -527,18 +579,20 @@ type PublicEvent struct {
Installation *Installation `json:"installation,omitempty"`
}
// PullRequestEvent is triggered when a pull request is assigned, unassigned,
// labeled, unlabeled, opened, closed, reopened, or synchronized.
// PullRequestEvent is triggered when a pull request is assigned, unassigned, labeled,
// unlabeled, opened, edited, closed, reopened, synchronize, ready_for_review,
// locked, unlocked, a pull request review is requested, or a review request is removed.
// 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.
// "opened", "edited", "closed", "ready_for_review", "locked", "unlocked", or "reopened".
// 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.
// While webhooks are also triggered when a pull request is synchronized, Events API timelines
// don't include pull request events with the "synchronize" action.
Action *string `json:"action,omitempty"`
Assignee *User `json:"assignee,omitempty"`
Number *int `json:"number,omitempty"`
@ -549,15 +603,22 @@ type PullRequestEvent struct {
// 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.
RequestedReviewer *User `json:"requested_reviewer,omitempty"`
// In the event that a team is requested instead of a user, "requested_team" gets sent in place of
// "requested_user" with the same delivery behavior.
RequestedTeam *Team `json:"requested_team,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"`
// The following fields are only populated when the Action is "synchronize".
Before *string `json:"before,omitempty"`
After *string `json:"after,omitempty"`
}
// PullRequestReviewEvent is triggered when a review is submitted on a pull
@ -604,13 +665,13 @@ type PullRequestReviewCommentEvent struct {
//
// 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"`
PushID *int64 `json:"push_id,omitempty"`
Head *string `json:"head,omitempty"`
Ref *string `json:"ref,omitempty"`
Size *int `json:"size,omitempty"`
Commits []*HeadCommit `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"`
@ -620,7 +681,7 @@ type PushEvent struct {
BaseRef *string `json:"base_ref,omitempty"`
Compare *string `json:"compare,omitempty"`
Repo *PushEventRepository `json:"repository,omitempty"`
HeadCommit *PushEventCommit `json:"head_commit,omitempty"`
HeadCommit *HeadCommit `json:"head_commit,omitempty"`
Pusher *User `json:"pusher,omitempty"`
Sender *User `json:"sender,omitempty"`
Installation *Installation `json:"installation,omitempty"`
@ -630,8 +691,8 @@ func (p PushEvent) String() string {
return Stringify(p)
}
// PushEventCommit represents a git commit in a GitHub PushEvent.
type PushEventCommit struct {
// HeadCommit represents a git commit in a GitHub PushEvent.
type HeadCommit struct {
Message *string `json:"message,omitempty"`
Author *CommitAuthor `json:"author,omitempty"`
URL *string `json:"url,omitempty"`
@ -650,7 +711,7 @@ type PushEventCommit struct {
Modified []string `json:"modified,omitempty"`
}
func (p PushEventCommit) String() string {
func (p HeadCommit) String() string {
return Stringify(p)
}
@ -668,6 +729,7 @@ type PushEventRepository struct {
PushedAt *Timestamp `json:"pushed_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
Homepage *string `json:"homepage,omitempty"`
PullsURL *string `json:"pulls_url,omitempty"`
Size *int `json:"size,omitempty"`
StargazersCount *int `json:"stargazers_count,omitempty"`
WatchersCount *int `json:"watchers_count,omitempty"`
@ -677,6 +739,8 @@ type PushEventRepository struct {
HasWiki *bool `json:"has_wiki,omitempty"`
HasPages *bool `json:"has_pages,omitempty"`
ForksCount *int `json:"forks_count,omitempty"`
Archived *bool `json:"archived,omitempty"`
Disabled *bool `json:"disabled,omitempty"`
OpenIssuesCount *int `json:"open_issues_count,omitempty"`
DefaultBranch *string `json:"default_branch,omitempty"`
MasterBranch *string `json:"master_branch,omitempty"`
@ -697,12 +761,14 @@ type PushEventRepoOwner struct {
Email *string `json:"email,omitempty"`
}
// ReleaseEvent is triggered when a release is published.
// ReleaseEvent is triggered when a release is published, unpublished, created,
// edited, deleted, or prereleased.
// 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 is the action that was performed. Possible values are: "published", "unpublished",
// "created", "edited", "deleted", or "prereleased".
Action *string `json:"action,omitempty"`
Release *RepositoryRelease `json:"release,omitempty"`
@ -712,7 +778,9 @@ type ReleaseEvent struct {
Installation *Installation `json:"installation,omitempty"`
}
// RepositoryEvent is triggered when a repository is created.
// RepositoryEvent is triggered when a repository is created, archived, unarchived,
// renamed, edited, transferred, made public, or made private. Organization hooks are
// also trigerred when a repository is deleted.
// The Webhook event name is "repository".
//
// Events of this type are not visible in timelines, they are only used to
@ -720,8 +788,9 @@ type ReleaseEvent struct {
//
// 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 is the action that was performed. Possible values are: "created",
// "deleted" (organization hooks only), "archived", "unarchived", "edited", "renamed",
// "transferred", "publicized", or "privatized".
Action *string `json:"action,omitempty"`
Repo *Repository `json:"repository,omitempty"`
@ -731,11 +800,27 @@ type RepositoryEvent struct {
Installation *Installation `json:"installation,omitempty"`
}
// RepositoryDispatchEvent is triggered when a client sends a POST request to the repository dispatch event endpoint.
//
// GitHub API docs: https://developer.github.com/v3/activity/events/types/#repositorydispatchevent
type RepositoryDispatchEvent struct {
// Action is the event_type that submitted with the repository dispatch payload. Value can be any string.
Action *string `json:"action,omitempty"`
Branch *string `json:"branch,omitempty"`
ClientPayload json.RawMessage `json:"client_payload,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 is the action that was performed. Possible values are: "create", "dismiss", "resolve".
Action *string `json:"action,omitempty"`
//The security alert of the vulnerable dependency.
@ -750,6 +835,21 @@ type RepositoryVulnerabilityAlertEvent struct {
DismissReason *string `json:"dismiss_reason,omitempty"`
DismissedAt *Timestamp `json:"dismissed_at,omitempty"`
} `json:"alert,omitempty"`
//The repository of the vulnerable dependency.
Repository *Repository `json:"repository,omitempty"`
}
// StarEvent is triggered when a star is added or removed from a repository.
// The Webhook event name is "star".
//
// GitHub API docs: https://developer.github.com/v3/activity/events/types/#starevent
type StarEvent struct {
// Action is the action that was performed. Possible values are: "created" or "deleted".
Action *string `json:"action,omitempty"`
// StarredAt is the time the star was created. It will be null for the "deleted" action.
StarredAt *Timestamp `json:"starred_at,omitempty"`
}
// StatusEvent is triggered when the status of a Git commit changes.
@ -815,6 +915,20 @@ type TeamAddEvent struct {
Installation *Installation `json:"installation,omitempty"`
}
// UserEvent is triggered when a user is created or deleted.
// The Webhook event name is "user".
//
// Only global webhooks can subscribe to this event type.
//
// GitHub API docs: https://developer.github.com/enterprise/v3/activity/events/types/#userevent-enterprise
type UserEvent struct {
User *User `json:"user,omitempty"`
// The action performed. Possible values are: "created" or "deleted".
Action *string `json:"action,omitempty"`
Enterprise *Enterprise `json:"enterprise,omitempty"`
Sender *User `json:"sender,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/
//

View File

@ -96,15 +96,16 @@ type GistListOptions struct {
// 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) {
// GitHub API docs: https://developer.github.com/v3/gists/#list-gists-for-a-user
// GitHub API docs: https://developer.github.com/v3/gists/#list-gists-for-the-authenticated-user
func (s *GistsService) List(ctx context.Context, user string, opts *GistListOptions) ([]*Gist, *Response, error) {
var u string
if user != "" {
u = fmt.Sprintf("users/%v/gists", user)
} else {
u = "gists"
}
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -125,9 +126,9 @@ func (s *GistsService) List(ctx context.Context, user string, opt *GistListOptio
// 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)
// GitHub API docs: https://developer.github.com/v3/gists/#list-public-gists
func (s *GistsService) ListAll(ctx context.Context, opts *GistListOptions) ([]*Gist, *Response, error) {
u, err := addOptions("gists/public", opts)
if err != nil {
return nil, nil, err
}
@ -148,9 +149,9 @@ func (s *GistsService) ListAll(ctx context.Context, opt *GistListOptions) ([]*Gi
// 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)
// GitHub API docs: https://developer.github.com/v3/gists/#list-starred-gists
func (s *GistsService) ListStarred(ctx context.Context, opts *GistListOptions) ([]*Gist, *Response, error) {
u, err := addOptions("gists/starred", opts)
if err != nil {
return nil, nil, err
}
@ -171,7 +172,7 @@ func (s *GistsService) ListStarred(ctx context.Context, opt *GistListOptions) ([
// Get a single gist.
//
// GitHub API docs: https://developer.github.com/v3/gists/#get-a-single-gist
// GitHub API docs: https://developer.github.com/v3/gists/#get-a-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)
@ -190,7 +191,7 @@ func (s *GistsService) Get(ctx context.Context, id string) (*Gist, *Response, er
// GetRevision gets a specific revision of a gist.
//
// GitHub API docs: https://developer.github.com/v3/gists/#get-a-specific-revision-of-a-gist
// GitHub API docs: https://developer.github.com/v3/gists/#get-a-gist-revision
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)
@ -228,7 +229,7 @@ func (s *GistsService) Create(ctx context.Context, gist *Gist) (*Gist, *Response
// Edit a gist.
//
// GitHub API docs: https://developer.github.com/v3/gists/#edit-a-gist
// GitHub API docs: https://developer.github.com/v3/gists/#update-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)
@ -248,9 +249,9 @@ 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, opt *ListOptions) ([]*GistCommit, *Response, error) {
func (s *GistsService) ListCommits(ctx context.Context, id string, opts *ListOptions) ([]*GistCommit, *Response, error) {
u := fmt.Sprintf("gists/%v/commits", id)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -341,8 +342,13 @@ func (s *GistsService) Fork(ctx context.Context, id string) (*Gist, *Response, e
// 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) {
func (s *GistsService) ListForks(ctx context.Context, id string, opts *ListOptions) ([]*GistFork, *Response, error) {
u := fmt.Sprintf("gists/%v/forks", id)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err

View File

@ -26,10 +26,10 @@ func (g GistComment) String() string {
// 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) {
// GitHub API docs: https://developer.github.com/v3/gists/comments/#list-gist-comments
func (s *GistsService) ListComments(ctx context.Context, gistID string, opts *ListOptions) ([]*GistComment, *Response, error) {
u := fmt.Sprintf("gists/%v/comments", gistID)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -50,7 +50,7 @@ func (s *GistsService) ListComments(ctx context.Context, gistID string, opt *Lis
// GetComment retrieves a single comment from a gist.
//
// GitHub API docs: https://developer.github.com/v3/gists/comments/#get-a-single-comment
// GitHub API docs: https://developer.github.com/v3/gists/comments/#get-a-gist-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)
@ -69,7 +69,7 @@ func (s *GistsService) GetComment(ctx context.Context, gistID string, commentID
// CreateComment creates a comment for a gist.
//
// GitHub API docs: https://developer.github.com/v3/gists/comments/#create-a-comment
// GitHub API docs: https://developer.github.com/v3/gists/comments/#create-a-gist-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)
@ -88,7 +88,7 @@ func (s *GistsService) CreateComment(ctx context.Context, gistID string, comment
// EditComment edits an existing gist comment.
//
// GitHub API docs: https://developer.github.com/v3/gists/comments/#edit-a-comment
// GitHub API docs: https://developer.github.com/v3/gists/comments/#update-a-gist-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)
@ -107,7 +107,7 @@ func (s *GistsService) EditComment(ctx context.Context, gistID string, commentID
// DeleteComment deletes a gist comment.
//
// GitHub API docs: https://developer.github.com/v3/gists/comments/#delete-a-comment
// GitHub API docs: https://developer.github.com/v3/gists/comments/#delete-a-gist-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)

View File

@ -6,9 +6,14 @@
package github
import (
"bytes"
"context"
"errors"
"fmt"
"strings"
"time"
"golang.org/x/crypto/openpgp"
)
// SignatureVerification represents GPG signature verification.
@ -26,7 +31,7 @@ type Commit struct {
Committer *CommitAuthor `json:"committer,omitempty"`
Message *string `json:"message,omitempty"`
Tree *Tree `json:"tree,omitempty"`
Parents []Commit `json:"parents,omitempty"`
Parents []*Commit `json:"parents,omitempty"`
Stats *CommitStats `json:"stats,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
URL *string `json:"url,omitempty"`
@ -37,6 +42,11 @@ type Commit struct {
// is only populated for requests that fetch GitHub data like
// Pulls.ListCommits, Repositories.ListCommits, etc.
CommentCount *int `json:"comment_count,omitempty"`
// SigningKey denotes a key to sign the commit with. If not nil this key will
// be used to sign the commit. The private key must be present and already
// decrypted. Ignored if Verification.Signature is defined.
SigningKey *openpgp.Entity `json:"-"`
}
func (c Commit) String() string {
@ -116,6 +126,13 @@ func (s *GitService) CreateCommit(ctx context.Context, owner string, repo string
if commit.Tree != nil {
body.Tree = commit.Tree.SHA
}
if commit.SigningKey != nil {
signature, err := createSignature(commit.SigningKey, body)
if err != nil {
return nil, nil, err
}
body.Signature = &signature
}
if commit.Verification != nil {
body.Signature = commit.Verification.Signature
}
@ -133,3 +150,51 @@ func (s *GitService) CreateCommit(ctx context.Context, owner string, repo string
return c, resp, nil
}
func createSignature(signingKey *openpgp.Entity, commit *createCommit) (string, error) {
if signingKey == nil || commit == nil {
return "", errors.New("createSignature: invalid parameters")
}
message, err := createSignatureMessage(commit)
if err != nil {
return "", err
}
writer := new(bytes.Buffer)
reader := bytes.NewReader([]byte(message))
if err := openpgp.ArmoredDetachSign(writer, signingKey, reader, nil); err != nil {
return "", err
}
return writer.String(), nil
}
func createSignatureMessage(commit *createCommit) (string, error) {
if commit == nil || commit.Message == nil || *commit.Message == "" || commit.Author == nil {
return "", errors.New("createSignatureMessage: invalid parameters")
}
var message []string
if commit.Tree != nil {
message = append(message, fmt.Sprintf("tree %s", *commit.Tree))
}
for _, parent := range commit.Parents {
message = append(message, fmt.Sprintf("parent %s", parent))
}
message = append(message, fmt.Sprintf("author %s <%s> %d %s", commit.Author.GetName(), commit.Author.GetEmail(), commit.Author.GetDate().Unix(), commit.Author.GetDate().Format("-0700")))
committer := commit.Committer
if committer == nil {
committer = commit.Author
}
// There needs to be a double newline after committer
message = append(message, fmt.Sprintf("committer %s <%s> %d %s\n", committer.GetName(), committer.GetEmail(), committer.GetDate().Unix(), committer.GetDate().Format("-0700")))
message = append(message, *commit.Message)
return strings.Join(message, "\n"), nil
}

View File

@ -7,8 +7,6 @@ package github
import (
"context"
"encoding/json"
"errors"
"fmt"
"net/url"
"strings"
@ -49,16 +47,12 @@ type updateRefRequest struct {
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.
// GetRef fetches a single reference in a repository.
//
// 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))
u := fmt.Sprintf("repos/%v/%v/git/ref/%v", owner, repo, refURLEscape(ref))
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
@ -66,80 +60,42 @@ func (s *GitService) GetRef(ctx context.Context, owner string, repo string, ref
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 {
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
// refURLEscape escapes every path segment of the given ref. Those must
// not contain escaped "/" - as "%2F" - or github will not recognize it.
func refURLEscape(ref string) string {
parts := strings.Split(ref, "/")
for i, s := range parts {
parts[i] = url.PathEscape(s)
}
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)
return strings.Join(parts, "/")
}
// ReferenceListOptions specifies optional parameters to the
// GitService.ListRefs method.
// GitService.ListMatchingRefs method.
type ReferenceListOptions struct {
Type string `url:"-"`
Ref string `url:"-"`
ListOptions
}
// ListRefs lists all refs in a repository.
// ListMatchingRefs lists references in a repository that match a supplied ref.
// Use an empty ref to list all references.
//
// 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)
// GitHub API docs: https://developer.github.com/v3/git/refs/#list-matching-references
func (s *GitService) ListMatchingRefs(ctx context.Context, owner, repo string, opts *ReferenceListOptions) ([]*Reference, *Response, error) {
var ref string
if opts != nil {
ref = strings.TrimPrefix(opts.Ref, "refs/")
}
u, err := addOptions(u, opt)
u := fmt.Sprintf("repos/%v/%v/git/matching-refs/%v", owner, repo, refURLEscape(ref))
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -209,7 +165,7 @@ func (s *GitService) UpdateRef(ctx context.Context, owner string, repo string, r
// 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))
u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, refURLEscape(ref))
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err

View File

@ -7,13 +7,14 @@ package github
import (
"context"
"encoding/json"
"fmt"
)
// Tree represents a GitHub tree.
type Tree struct {
SHA *string `json:"sha,omitempty"`
Entries []TreeEntry `json:"tree,omitempty"`
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
@ -43,6 +44,53 @@ func (t TreeEntry) String() string {
return Stringify(t)
}
// treeEntryWithFileDelete is used internally to delete a file whose
// Content and SHA fields are empty. It does this by removing the "omitempty"
// tag modifier on the SHA field which causes the GitHub API to receive
// {"sha":null} and thereby delete the file.
type treeEntryWithFileDelete struct {
SHA *string `json:"sha"`
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) MarshalJSON() ([]byte, error) {
if t.SHA == nil && t.Content == nil {
return json.Marshal(struct {
SHA *string `json:"sha"`
Path *string `json:"path,omitempty"`
Mode *string `json:"mode,omitempty"`
Type *string `json:"type,omitempty"`
}{
nil,
t.Path,
t.Mode,
t.Type,
})
}
return json.Marshal(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"`
}{
SHA: t.SHA,
Path: t.Path,
Mode: t.Mode,
Type: t.Type,
Size: t.Size,
Content: t.Content,
URL: t.URL,
})
}
// 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
@ -68,8 +116,8 @@ func (s *GitService) GetTree(ctx context.Context, owner string, repo string, sha
// createTree represents the body of a CreateTree request.
type createTree struct {
BaseTree string `json:"base_tree,omitempty"`
Entries []TreeEntry `json:"tree"`
BaseTree string `json:"base_tree,omitempty"`
Entries []interface{} `json:"tree"`
}
// CreateTree creates a new tree in a repository. If both a tree and a nested
@ -77,12 +125,27 @@ type createTree struct {
// 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) {
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)
newEntries := make([]interface{}, 0, len(entries))
for _, entry := range entries {
if entry.Content == nil && entry.SHA == nil {
newEntries = append(newEntries, treeEntryWithFileDelete{
Path: entry.Path,
Mode: entry.Mode,
Type: entry.Type,
Size: entry.Size,
URL: entry.URL,
})
continue
}
newEntries = append(newEntries, entry)
}
body := &createTree{
BaseTree: baseTree,
Entries: entries,
Entries: newEntries,
}
req, err := s.client.NewRequest("POST", u, body)
if err != nil {

View File

@ -4,6 +4,7 @@
// license that can be found in the LICENSE file.
//go:generate go run gen-accessors.go
//go:generate go run gen-stringify-test.go
package github
@ -57,18 +58,12 @@ const (
// 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"
@ -90,27 +85,9 @@ const (
// 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"
@ -129,8 +106,35 @@ const (
// 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"
// https://developer.github.com/changes/2019-03-14-enabling-disabling-pages/
mediaTypeEnablePagesAPIPreview = "application/vnd.github.switcheroo-preview+json"
// https://developer.github.com/changes/2019-04-24-vulnerability-alerts/
mediaTypeRequiredVulnerabilityAlertsPreview = "application/vnd.github.dorian-preview+json"
// https://developer.github.com/changes/2019-06-04-automated-security-fixes/
mediaTypeRequiredAutomatedSecurityFixesPreview = "application/vnd.github.london-preview+json"
// https://developer.github.com/changes/2019-05-29-update-branch-api/
mediaTypeUpdatePullRequestBranchPreview = "application/vnd.github.lydian-preview+json"
// https://developer.github.com/changes/2019-04-11-pulls-branches-for-commit/
mediaTypeListPullsOrBranchesForCommitPreview = "application/vnd.github.groot-preview+json"
// https://developer.github.com/v3/previews/#repository-creation-permissions
mediaTypeMemberAllowedRepoCreationTypePreview = "application/vnd.github.surtur-preview+json"
// https://developer.github.com/v3/previews/#create-and-use-repository-templates
mediaTypeRepositoryTemplatePreview = "application/vnd.github.baptiste-preview+json"
// https://developer.github.com/changes/2019-10-03-multi-line-comments/
mediaTypeMultiLineCommentsPreview = "application/vnd.github.comfort-fade-preview+json"
// https://developer.github.com/changes/2019-11-05-deprecated-passwords-and-authorizations-api/
mediaTypeOAuthAppPreview = "application/vnd.github.doctor-strange-preview+json"
// https://developer.github.com/changes/2019-12-03-internal-visibility-changes/
mediaTypeRepositoryVisibilityPreview = "application/vnd.github.nebula-preview+json"
)
// A Client manages communication with the GitHub API.
@ -155,11 +159,13 @@ type Client struct {
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.
Actions *ActionsService
Activity *ActivityService
Admin *AdminService
Apps *AppsService
Authorizations *AuthorizationsService
Checks *ChecksService
CodeScanning *CodeScanningService
Gists *GistsService
Git *GitService
Gitignores *GitignoresService
@ -183,7 +189,7 @@ type service struct {
}
// ListOptions specifies the optional parameters to various List methods that
// support pagination.
// support offset pagination.
type ListOptions struct {
// For paginated result sets, page of results to retrieve.
Page int `url:"page,omitempty"`
@ -192,6 +198,16 @@ type ListOptions struct {
PerPage int `url:"per_page,omitempty"`
}
// ListCursorOptions specifies the optional parameters to various List methods that
// support cursor pagination.
type ListCursorOptions struct {
// For paginated result sets, page of results to retrieve.
Page string `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"`
@ -215,10 +231,10 @@ type RawOptions struct {
Type RawType
}
// addOptions adds the parameters in opt as URL query parameters to s. opt
// addOptions adds the parameters in opts as URL query parameters to s. opts
// must be a struct whose fields may contain "url" tags.
func addOptions(s string, opt interface{}) (string, error) {
v := reflect.ValueOf(opt)
func addOptions(s string, opts interface{}) (string, error) {
v := reflect.ValueOf(opts)
if v.Kind() == reflect.Ptr && v.IsNil() {
return s, nil
}
@ -228,7 +244,7 @@ func addOptions(s string, opt interface{}) (string, error) {
return s, err
}
qs, err := query.Values(opt)
qs, err := query.Values(opts)
if err != nil {
return s, err
}
@ -238,23 +254,25 @@ func addOptions(s string, opt interface{}) (string, error) {
}
// NewClient returns a new GitHub API client. If a nil httpClient is
// provided, http.DefaultClient will be used. To use API methods which require
// provided, a new http.Client 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
httpClient = &http.Client{}
}
baseURL, _ := url.Parse(defaultBaseURL)
uploadURL, _ := url.Parse(uploadBaseURL)
c := &Client{client: httpClient, BaseURL: baseURL, UserAgent: userAgent, UploadURL: uploadURL}
c.common.client = c
c.Actions = (*ActionsService)(&c.common)
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.CodeScanning = (*CodeScanningService)(&c.common)
c.Gists = (*GistsService)(&c.common)
c.Git = (*GitService)(&c.common)
c.Gitignores = (*GitignoresService)(&c.common)
@ -275,13 +293,18 @@ func NewClient(httpClient *http.Client) *Client {
}
// 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.
// base URL and upload URL (often is your GitHub Enterprise hostname).
// If the base URL does not have the suffix "/api/v3/", it will be added automatically.
// If the upload URL does not have the suffix "/api/uploads", it will be added automatically.
// If a nil httpClient is provided, a new http.Client 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.
//
// Another important thing is that by default, the GitHub Enterprise URL format
// should be http(s)://[hostname]/api/v3/ or you will always receive the 406 status code.
// The upload URL format should be http(s)://[hostname]/api/uploads/.
func NewEnterpriseClient(baseURL, uploadURL string, httpClient *http.Client) (*Client, error) {
baseEndpoint, err := url.Parse(baseURL)
if err != nil {
@ -290,6 +313,9 @@ func NewEnterpriseClient(baseURL, uploadURL string, httpClient *http.Client) (*C
if !strings.HasSuffix(baseEndpoint.Path, "/") {
baseEndpoint.Path += "/"
}
if !strings.HasSuffix(baseEndpoint.Path, "/api/v3/") {
baseEndpoint.Path += "api/v3/"
}
uploadEndpoint, err := url.Parse(uploadURL)
if err != nil {
@ -298,6 +324,9 @@ func NewEnterpriseClient(baseURL, uploadURL string, httpClient *http.Client) (*C
if !strings.HasSuffix(uploadEndpoint.Path, "/") {
uploadEndpoint.Path += "/"
}
if !strings.HasSuffix(uploadEndpoint.Path, "/api/uploads/") {
uploadEndpoint.Path += "api/uploads/"
}
c := NewClient(httpClient)
c.BaseURL = baseEndpoint
@ -321,7 +350,7 @@ func (c *Client) NewRequest(method, urlStr string, body interface{}) (*http.Requ
var buf io.ReadWriter
if body != nil {
buf = new(bytes.Buffer)
buf = &bytes.Buffer{}
enc := json.NewEncoder(buf)
enc.SetEscapeHTML(false)
err := enc.Encode(body)
@ -382,12 +411,27 @@ type Response struct {
// 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.
//
// These fields support what is called "offset pagination" and should
// be used with the ListOptions struct.
NextPage int
PrevPage int
FirstPage int
LastPage int
// Additionally, some APIs support "cursor pagination" instead of offset.
// This means that a token points directly to the next record which
// can lead to O(1) performance compared to O(n) performance provided
// by offset pagination.
//
// For APIs that support cursor pagination (such as
// TeamsService.ListIDPGroupsInOrganization), the following field
// will be populated to point to the next page.
//
// To use this token, set ListCursorOptions.Page to this value before
// calling the endpoint again.
NextPageToken string
// Explicitly specify the Rate type so Rate's String() receiver doesn't
// propagate to Response.
Rate Rate
@ -432,7 +476,9 @@ func (r *Response) populatePageValues() {
for _, segment := range segments[1:] {
switch strings.TrimSpace(segment) {
case `rel="next"`:
r.NextPage, _ = strconv.Atoi(page)
if r.NextPage, err = strconv.Atoi(page); err != nil {
r.NextPageToken = page
}
case `rel="prev"`:
r.PrevPage, _ = strconv.Atoi(page)
case `rel="first"`:
@ -470,9 +516,12 @@ func parseRate(r *http.Response) Rate {
// 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,
// The provided ctx must be non-nil, if it is nil an error is returned. 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) {
if ctx == nil {
return nil, errors.New("context must be non-nil")
}
req = withContext(ctx, req)
rateLimitCategory := category(req.URL.Path)
@ -614,7 +663,7 @@ 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 ".
// remaining value of 0.
type RateLimitError struct {
Rate Rate // Rate specifies last known rate limit for the client
Response *http.Response // HTTP response that caused this error
@ -624,7 +673,7 @@ type RateLimitError struct {
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())))
r.Response.StatusCode, r.Message, formatRateReset(time.Until(r.Rate.Reset.Time)))
}
// AcceptedError occurs when GitHub returns 202 Accepted response with an
@ -690,6 +739,10 @@ These are the possible validation error codes:
some resources return this (e.g. github.User.CreateKey()), additional
information is set in the Message field of the Error
GitHub error responses structure are often undocumented and inconsistent.
Sometimes error is just a simple string (Issue #540).
In such cases, Message represents an error message as a workaround.
GitHub API docs: https://developer.github.com/v3/#client-errors
*/
type Error struct {
@ -704,12 +757,19 @@ func (e *Error) Error() string {
e.Code, e.Field, e.Resource)
}
func (e *Error) UnmarshalJSON(data []byte) error {
type aliasError Error // avoid infinite recursion by using type alias.
if err := json.Unmarshal(data, (*aliasError)(e)); err != nil {
return json.Unmarshal(data, &e.Message) // data can be json string.
}
return nil
}
// 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.
// API error responses are expected to have response
// body, and a JSON response body that maps to ErrorResponse.
//
// The error type will be *RateLimitError for rate limit exceeded errors,
// *AcceptedError for 202 Accepted status codes,
@ -726,10 +786,14 @@ func CheckResponse(r *http.Response) error {
if err == nil && data != nil {
json.Unmarshal(data, errorResponse)
}
// Re-populate error response body because GitHub error responses are often
// undocumented and inconsistent.
// Issue #1136, #540.
r.Body = ioutil.NopCloser(bytes.NewBuffer(data))
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 "):
case r.StatusCode == http.StatusForbidden && r.Header.Get(headerRateRemaining) == "0":
return &RateLimitError{
Rate: parseRate(r),
Response: errorResponse.Response,
@ -858,6 +922,24 @@ func (c *Client) RateLimits(ctx context.Context) (*RateLimits, *Response, error)
return response.Resources, resp, nil
}
func setCredentialsAsHeaders(req *http.Request, id, secret string) *http.Request {
// 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.
convertedRequest := new(http.Request)
*convertedRequest = *req
convertedRequest.Header = make(http.Header, len(req.Header))
for k, s := range req.Header {
convertedRequest.Header[k] = append([]string(nil), s...)
}
convertedRequest.SetBasicAuth(id, secret)
return convertedRequest
}
/*
UnauthenticatedRateLimitedTransport allows you to make unauthenticated calls
that need to use a higher rate limit associated with your OAuth application.
@ -868,8 +950,8 @@ that need to use a higher rate limit associated with your OAuth application.
}
client := github.NewClient(t.Client())
This will append the querystring params client_id=xxx&client_secret=yyy to all
requests.
This will add the client id and secret as a base64-encoded string in the format
ClientID:ClientSecret and apply it as an "Authorization": "Basic" header.
See https://developer.github.com/v3/#unauthenticated-rate-limited-requests for
more information.
@ -898,22 +980,7 @@ func (t *UnauthenticatedRateLimitedTransport) RoundTrip(req *http.Request) (*htt
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()
req2 := setCredentialsAsHeaders(req, t.ClientID, t.ClientSecret)
// Make the HTTP request.
return t.transport().RoundTrip(req2)
}
@ -947,20 +1014,7 @@ type BasicAuthTransport struct {
// 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)
req2 := setCredentialsAsHeaders(req, t.Username, t.Password)
if t.OTP != "" {
req2.Header.Set(headerOTP, t.OTP)
}

View File

@ -29,7 +29,7 @@ func (g Gitignore) String() string {
// 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) {
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
@ -46,8 +46,8 @@ func (s GitignoresService) List(ctx context.Context) ([]string, *Response, error
// 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) {
// GitHub API docs: https://developer.github.com/v3/gitignore/#get-a-gitignore-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 {

View File

@ -39,7 +39,7 @@ func (s *InteractionsService) GetRestrictionsForOrg(ctx context.Context, organiz
// 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
// GitHub API docs: https://developer.github.com/v3/interactions/orgs/#set-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)

View File

@ -39,7 +39,7 @@ func (s *InteractionsService) GetRestrictionsForRepo(ctx context.Context, owner,
// 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
// GitHub API docs: https://developer.github.com/v3/interactions/repos/#set-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)

View File

@ -26,36 +26,37 @@ type IssuesService service
// 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"`
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"`
AuthorAssociation *string `json:"author_association,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"`
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".
@ -128,28 +129,29 @@ type PullRequestLinks struct {
// 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) {
// GitHub API docs: https://developer.github.com/v3/issues/#list-issues-assigned-to-the-authenticated-user
// GitHub API docs: https://developer.github.com/v3/issues/#list-user-account-issues-assigned-to-the-authenticated-user
func (s *IssuesService) List(ctx context.Context, all bool, opts *IssueListOptions) ([]*Issue, *Response, error) {
var u string
if all {
u = "issues"
} else {
u = "user/issues"
}
return s.listIssues(ctx, u, opt)
return s.listIssues(ctx, u, opts)
}
// 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) {
// GitHub API docs: https://developer.github.com/v3/issues/#list-organization-issues-assigned-to-the-authenticated-user
func (s *IssuesService) ListByOrg(ctx context.Context, org string, opts *IssueListOptions) ([]*Issue, *Response, error) {
u := fmt.Sprintf("orgs/%v/issues", org)
return s.listIssues(ctx, u, opt)
return s.listIssues(ctx, u, opts)
}
func (s *IssuesService) listIssues(ctx context.Context, u string, opt *IssueListOptions) ([]*Issue, *Response, error) {
u, err := addOptions(u, opt)
func (s *IssuesService) listIssues(ctx context.Context, u string, opts *IssueListOptions) ([]*Issue, *Response, error) {
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -160,7 +162,7 @@ func (s *IssuesService) listIssues(ctx context.Context, u string, opt *IssueList
}
// TODO: remove custom Accept headers when APIs fully launch.
acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLockReasonPreview}
req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
var issues []*Issue
@ -214,10 +216,10 @@ type IssueListByRepoOptions struct {
// 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) {
// GitHub API docs: https://developer.github.com/v3/issues/#list-repository-issues
func (s *IssuesService) ListByRepo(ctx context.Context, owner string, repo string, opts *IssueListByRepoOptions) ([]*Issue, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues", owner, repo)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -228,7 +230,7 @@ func (s *IssuesService) ListByRepo(ctx context.Context, owner string, repo strin
}
// TODO: remove custom Accept headers when APIs fully launch.
acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeIntegrationPreview}
acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeIntegrationPreview}
req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
var issues []*Issue
@ -242,7 +244,7 @@ func (s *IssuesService) ListByRepo(ctx context.Context, owner string, repo strin
// Get a single issue.
//
// GitHub API docs: https://developer.github.com/v3/issues/#get-a-single-issue
// GitHub API docs: https://developer.github.com/v3/issues/#get-an-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)
@ -251,7 +253,7 @@ func (s *IssuesService) Get(ctx context.Context, owner string, repo string, numb
}
// TODO: remove custom Accept headers when APIs fully launch.
acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLockReasonPreview}
req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
issue := new(Issue)
@ -273,9 +275,6 @@ func (s *IssuesService) Create(ctx context.Context, owner string, repo string, i
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 {
@ -287,7 +286,7 @@ func (s *IssuesService) Create(ctx context.Context, owner string, repo string, i
// Edit an issue.
//
// GitHub API docs: https://developer.github.com/v3/issues/#edit-an-issue
// GitHub API docs: https://developer.github.com/v3/issues/#update-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)
@ -295,9 +294,6 @@ func (s *IssuesService) Edit(ctx context.Context, owner string, repo string, num
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 {
@ -319,14 +315,14 @@ type LockIssueOptions struct {
// 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) {
func (s *IssuesService) Lock(ctx context.Context, owner string, repo string, number int, opts *LockIssueOptions) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/%d/lock", owner, repo, number)
req, err := s.client.NewRequest("PUT", u, opt)
req, err := s.client.NewRequest("PUT", u, opts)
if err != nil {
return nil, err
}
if opt != nil {
if opts != nil {
req.Header.Set("Accept", mediaTypeLockReasonPreview)
}

View File

@ -14,9 +14,9 @@ import (
// 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) {
func (s *IssuesService) ListAssignees(ctx context.Context, owner, repo string, opts *ListOptions) ([]*User, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/assignees", owner, repo)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -36,7 +36,7 @@ func (s *IssuesService) ListAssignees(ctx context.Context, owner, repo string, o
// IsAssignee checks if a user is an assignee for the specified repository.
//
// GitHub API docs: https://developer.github.com/v3/issues/assignees/#check-assignee
// GitHub API docs: https://developer.github.com/v3/issues/assignees/#check-if-a-user-can-be-assigned
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)

View File

@ -36,13 +36,13 @@ func (i IssueComment) String() string {
// IssuesService.ListComments method.
type IssueListCommentsOptions struct {
// Sort specifies how to sort comments. Possible values are: created, updated.
Sort string `url:"sort,omitempty"`
Sort *string `url:"sort,omitempty"`
// Direction in which to sort comments. Possible values are: asc, desc.
Direction string `url:"direction,omitempty"`
Direction *string `url:"direction,omitempty"`
// Since filters comments by time.
Since time.Time `url:"since,omitempty"`
Since *time.Time `url:"since,omitempty"`
ListOptions
}
@ -50,15 +50,16 @@ type IssueListCommentsOptions struct {
// 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) {
// GitHub API docs: https://developer.github.com/v3/issues/comments/#list-issue-comments
// GitHub API docs: https://developer.github.com/v3/issues/comments/#list-issue-comments-for-a-repository
func (s *IssuesService) ListComments(ctx context.Context, owner string, repo string, number int, opts *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)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -82,7 +83,7 @@ func (s *IssuesService) ListComments(ctx context.Context, owner string, repo str
// GetComment fetches the specified issue comment.
//
// GitHub API docs: https://developer.github.com/v3/issues/comments/#get-a-single-comment
// GitHub API docs: https://developer.github.com/v3/issues/comments/#get-an-issue-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)
@ -105,7 +106,7 @@ func (s *IssuesService) GetComment(ctx context.Context, owner string, repo strin
// CreateComment creates a new comment on the specified issue.
//
// GitHub API docs: https://developer.github.com/v3/issues/comments/#create-a-comment
// GitHub API docs: https://developer.github.com/v3/issues/comments/#create-an-issue-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)
@ -124,7 +125,7 @@ func (s *IssuesService) CreateComment(ctx context.Context, owner string, repo st
// 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
// GitHub API docs: https://developer.github.com/v3/issues/comments/#update-an-issue-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)
@ -142,7 +143,7 @@ func (s *IssuesService) EditComment(ctx context.Context, owner string, repo stri
// DeleteComment deletes an issue comment.
//
// GitHub API docs: https://developer.github.com/v3/issues/comments/#delete-a-comment
// GitHub API docs: https://developer.github.com/v3/issues/comments/#delete-an-issue-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)

View File

@ -63,28 +63,42 @@ type IssueEvent struct {
// head_ref_deleted, head_ref_restored
// The pull requests branch was deleted or restored.
//
// review_dismissed
// The review was dismissed and `DismissedReview` will be populated below.
//
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"`
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"`
DismissedReview *DismissedReview `json:"dismissed_review,omitempty"`
}
// DismissedReview represents details for 'dismissed_review' events.
type DismissedReview struct {
// State represents the state of the dismissed review.
// Possible values are: "commented", "approved", and "changes_requested".
State *string `json:"state,omitempty"`
ReviewID *int64 `json:"review_id,omitempty"`
DismissalMessage *string `json:"dismissal_message,omitempty"`
DismissalCommitID *string `json:"dismissal_commit_id,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) {
// GitHub API docs: https://developer.github.com/v3/issues/events/#list-issue-events
func (s *IssuesService) ListIssueEvents(ctx context.Context, owner, repo string, number int, opts *ListOptions) ([]*IssueEvent, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/%v/events", owner, repo, number)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -108,10 +122,10 @@ func (s *IssuesService) ListIssueEvents(ctx context.Context, owner, repo string,
// 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) {
// GitHub API docs: https://developer.github.com/v3/issues/events/#list-issue-events-for-a-repository
func (s *IssuesService) ListRepositoryEvents(ctx context.Context, owner, repo string, opts *ListOptions) ([]*IssueEvent, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/events", owner, repo)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -132,7 +146,7 @@ func (s *IssuesService) ListRepositoryEvents(ctx context.Context, owner, repo st
// GetEvent returns the specified issue event.
//
// GitHub API docs: https://developer.github.com/v3/issues/events/#get-a-single-event
// GitHub API docs: https://developer.github.com/v3/issues/events/#get-an-issue-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)

View File

@ -27,10 +27,10 @@ func (l Label) String() string {
// 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) {
// GitHub API docs: https://developer.github.com/v3/issues/labels/#list-labels-for-a-repository
func (s *IssuesService) ListLabels(ctx context.Context, owner string, repo string, opts *ListOptions) ([]*Label, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/labels", owner, repo)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -40,9 +40,6 @@ func (s *IssuesService) ListLabels(ctx context.Context, owner string, repo strin
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 {
@ -54,7 +51,7 @@ func (s *IssuesService) ListLabels(ctx context.Context, owner string, repo strin
// GetLabel gets a single label.
//
// GitHub API docs: https://developer.github.com/v3/issues/labels/#get-a-single-label
// GitHub API docs: https://developer.github.com/v3/issues/labels/#get-a-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)
@ -62,9 +59,6 @@ func (s *IssuesService) GetLabel(ctx context.Context, owner string, repo string,
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 {
@ -84,9 +78,6 @@ func (s *IssuesService) CreateLabel(ctx context.Context, owner string, repo stri
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 {
@ -106,9 +97,6 @@ func (s *IssuesService) EditLabel(ctx context.Context, owner string, repo string
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 {
@ -132,10 +120,10 @@ func (s *IssuesService) DeleteLabel(ctx context.Context, owner string, repo stri
// 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) {
// GitHub API docs: https://developer.github.com/v3/issues/labels/#list-labels-for-an-issue
func (s *IssuesService) ListLabelsByIssue(ctx context.Context, owner string, repo string, number int, opts *ListOptions) ([]*Label, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -145,9 +133,6 @@ func (s *IssuesService) ListLabelsByIssue(ctx context.Context, owner string, rep
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 {
@ -167,9 +152,6 @@ func (s *IssuesService) AddLabelsToIssue(ctx context.Context, owner string, repo
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 {
@ -189,15 +171,12 @@ func (s *IssuesService) RemoveLabelForIssue(ctx context.Context, owner string, r
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
// GitHub API docs: https://developer.github.com/v3/issues/labels/#set-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)
@ -205,9 +184,6 @@ func (s *IssuesService) ReplaceLabelsForIssue(ctx context.Context, owner string,
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 {
@ -227,18 +203,15 @@ func (s *IssuesService) RemoveLabelsForIssue(ctx context.Context, owner string,
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) {
// GitHub API docs: https://developer.github.com/v3/issues/labels/#list-labels-for-issues-in-a-milestone
func (s *IssuesService) ListLabelsForMilestone(ctx context.Context, owner string, repo string, number int, opts *ListOptions) ([]*Label, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/milestones/%d/labels", owner, repo, number)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -248,9 +221,6 @@ func (s *IssuesService) ListLabelsForMilestone(ctx context.Context, owner string
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 {

View File

@ -55,10 +55,10 @@ type MilestoneListOptions struct {
// 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) {
// GitHub API docs: https://developer.github.com/v3/issues/milestones/#list-milestones
func (s *IssuesService) ListMilestones(ctx context.Context, owner string, repo string, opts *MilestoneListOptions) ([]*Milestone, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/milestones", owner, repo)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -79,7 +79,7 @@ func (s *IssuesService) ListMilestones(ctx context.Context, owner string, repo s
// GetMilestone gets a single milestone.
//
// GitHub API docs: https://developer.github.com/v3/issues/milestones/#get-a-single-milestone
// GitHub API docs: https://developer.github.com/v3/issues/milestones/#get-a-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)

View File

@ -131,10 +131,10 @@ type Source struct {
// 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) {
// GitHub API docs: https://developer.github.com/v3/issues/timeline/#list-timeline-events-for-an-issue
func (s *IssuesService) ListIssueTimeline(ctx context.Context, owner, repo string, number int, opts *ListOptions) ([]*Timeline, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/%v/timeline", owner, repo, number)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}

View File

@ -78,7 +78,7 @@ func (s *LicensesService) List(ctx context.Context) ([]*License, *Response, erro
// Get extended metadata for one license.
//
// GitHub API docs: https://developer.github.com/v3/licenses/#get-an-individual-license
// GitHub API docs: https://developer.github.com/v3/licenses/#get-a-license
func (s *LicensesService) Get(ctx context.Context, licenseName string) (*License, *Response, error) {
u := fmt.Sprintf("licenses/%s", licenseName)

View File

@ -46,9 +46,11 @@ var (
"commit_comment": "CommitCommentEvent",
"create": "CreateEvent",
"delete": "DeleteEvent",
"deploy_key": "DeployKeyEvent",
"deployment": "DeploymentEvent",
"deployment_status": "DeploymentStatusEvent",
"fork": "ForkEvent",
"github_app_authorization": "GitHubAppAuthorizationEvent",
"gollum": "GollumEvent",
"installation": "InstallationEvent",
"installation_repositories": "InstallationRepositoriesEvent",
@ -58,9 +60,11 @@ var (
"marketplace_purchase": "MarketplacePurchaseEvent",
"member": "MemberEvent",
"membership": "MembershipEvent",
"meta": "MetaEvent",
"milestone": "MilestoneEvent",
"organization": "OrganizationEvent",
"org_block": "OrgBlockEvent",
"package": "PackageEvent",
"page_build": "PageBuildEvent",
"ping": "PingEvent",
"project": "ProjectEvent",
@ -72,11 +76,14 @@ var (
"pull_request": "PullRequestEvent",
"push": "PushEvent",
"repository": "RepositoryEvent",
"repository_dispatch": "RepositoryDispatchEvent",
"repository_vulnerability_alert": "RepositoryVulnerabilityAlertEvent",
"release": "ReleaseEvent",
"star": "StarEvent",
"status": "StatusEvent",
"team": "TeamEvent",
"team_add": "TeamAddEvent",
"user": "UserEvent",
"watch": "WatchEvent",
}
)
@ -129,7 +136,9 @@ func messageMAC(signature string) ([]byte, func() hash.Hash, error) {
// 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.
// secretToken is the GitHub Webhook secret token.
// If your webhook does not contain a secret token, you can pass nil or an empty slice.
// This is intended for local development purposes only and all webhooks should ideally set up a secret token.
//
// Example usage:
//
@ -139,7 +148,7 @@ func messageMAC(signature string) ([]byte, func() hash.Hash, error) {
// // Process payload...
// }
//
func ValidatePayload(r *http.Request, secretKey []byte) (payload []byte, err error) {
func ValidatePayload(r *http.Request, secretToken []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 {
@ -175,25 +184,30 @@ func ValidatePayload(r *http.Request, secretKey []byte) (payload []byte, err err
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
// Only validate the signature if a secret token exists. This is intended for
// local development only and all webhooks should ideally set up a secret token.
if len(secretToken) > 0 {
sig := r.Header.Get(signatureHeader)
if err := ValidateSignature(sig, body, secretToken); 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.
// secretToken is the GitHub Webhook secret token.
//
// GitHub API docs: https://developer.github.com/webhooks/securing/#validating-payloads-from-github
func ValidateSignature(signature string, payload, secretKey []byte) error {
func ValidateSignature(signature string, payload, secretToken []byte) error {
messageMAC, hashFunc, err := messageMAC(signature)
if err != nil {
return err
}
if !checkMAC(payload, messageMAC, secretKey, hashFunc) {
if !checkMAC(payload, messageMAC, secretToken, hashFunc) {
return errors.New("payload signature check failed")
}
return nil

View File

@ -74,14 +74,14 @@ type startMigration struct {
// 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) {
// GitHub API docs: https://developer.github.com/v3/migrations/orgs/#start-an-organization-migration
func (s *MigrationService) StartMigration(ctx context.Context, org string, repos []string, opts *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)
if opts != nil {
body.LockRepositories = Bool(opts.LockRepositories)
body.ExcludeAttachments = Bool(opts.ExcludeAttachments)
}
req, err := s.client.NewRequest("POST", u, body)
@ -103,9 +103,13 @@ func (s *MigrationService) StartMigration(ctx context.Context, org string, repos
// 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) {
// GitHub API docs: https://developer.github.com/v3/migrations/orgs/#list-organization-migrations
func (s *MigrationService) ListMigrations(ctx context.Context, org string, opts *ListOptions) ([]*Migration, *Response, error) {
u := fmt.Sprintf("orgs/%v/migrations", org)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
@ -127,7 +131,7 @@ func (s *MigrationService) ListMigrations(ctx context.Context, org string) ([]*M
// 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
// GitHub API docs: https://developer.github.com/v3/migrations/orgs/#get-an-organization-migration-status
func (s *MigrationService) MigrationStatus(ctx context.Context, org string, id int64) (*Migration, *Response, error) {
u := fmt.Sprintf("orgs/%v/migrations/%v", org, id)
@ -151,7 +155,7 @@ func (s *MigrationService) MigrationStatus(ctx context.Context, org string, id i
// 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
// GitHub API docs: https://developer.github.com/v3/migrations/orgs/#download-an-organization-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)
@ -188,7 +192,7 @@ func (s *MigrationService) MigrationArchiveURL(ctx context.Context, org string,
// 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
// GitHub API docs: https://developer.github.com/v3/migrations/orgs/#delete-an-organization-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)
@ -208,7 +212,7 @@ func (s *MigrationService) DeleteMigration(ctx context.Context, org string, id i
// 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
// GitHub API docs: https://developer.github.com/v3/migrations/orgs/#unlock-an-organization-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)

View File

@ -106,7 +106,7 @@ type Import struct {
// 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"`
ProjectChoices []*Import `json:"project_choices,omitempty"`
}
func (i Import) String() string {
@ -146,7 +146,7 @@ func (f LargeFile) String() string {
// StartImport initiates a repository import.
//
// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#start-an-import
// GitHub API docs: https://developer.github.com/v3/migrations/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)
@ -154,9 +154,6 @@ func (s *MigrationService) StartImport(ctx context.Context, owner, repo string,
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 {
@ -168,7 +165,7 @@ func (s *MigrationService) StartImport(ctx context.Context, owner, repo string,
// 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
// GitHub API docs: https://developer.github.com/v3/migrations/source_imports/#get-an-import-status
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)
@ -176,9 +173,6 @@ func (s *MigrationService) ImportProgress(ctx context.Context, owner, repo strin
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 {
@ -190,7 +184,7 @@ func (s *MigrationService) ImportProgress(ctx context.Context, owner, repo strin
// UpdateImport initiates a repository import.
//
// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#update-existing-import
// GitHub API docs: https://developer.github.com/v3/migrations/source_imports/#update-an-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)
@ -198,9 +192,6 @@ func (s *MigrationService) UpdateImport(ctx context.Context, owner, repo string,
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 {
@ -222,7 +213,7 @@ func (s *MigrationService) UpdateImport(ctx context.Context, owner, repo string,
// 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
// GitHub API docs: https://developer.github.com/v3/migrations/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)
@ -230,9 +221,6 @@ func (s *MigrationService) CommitAuthors(ctx context.Context, owner, repo string
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 {
@ -246,7 +234,7 @@ func (s *MigrationService) CommitAuthors(ctx context.Context, owner, repo string
// 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
// GitHub API docs: https://developer.github.com/v3/migrations/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)
@ -254,9 +242,6 @@ func (s *MigrationService) MapCommitAuthor(ctx context.Context, owner, repo stri
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 {
@ -270,7 +255,7 @@ func (s *MigrationService) MapCommitAuthor(ctx context.Context, owner, repo stri
// 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
// GitHub API docs: https://developer.github.com/v3/migrations/source_imports/#update-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)
@ -278,9 +263,6 @@ func (s *MigrationService) SetLFSPreference(ctx context.Context, owner, repo str
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 {
@ -292,7 +274,7 @@ func (s *MigrationService) SetLFSPreference(ctx context.Context, owner, repo str
// LargeFiles lists files larger than 100MB found during the import.
//
// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#get-large-files
// GitHub API docs: https://developer.github.com/v3/migrations/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)
@ -300,9 +282,6 @@ func (s *MigrationService) LargeFiles(ctx context.Context, owner, repo string) (
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 {
@ -314,7 +293,7 @@ func (s *MigrationService) LargeFiles(ctx context.Context, owner, repo string) (
// CancelImport stops an import for a repository.
//
// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#cancel-an-import
// GitHub API docs: https://developer.github.com/v3/migrations/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)
@ -322,8 +301,5 @@ func (s *MigrationService) CancelImport(ctx context.Context, owner, repo string)
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)
}

View File

@ -68,13 +68,13 @@ type startUserMigration struct {
// 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) {
func (s *MigrationService) StartUserMigration(ctx context.Context, repos []string, opts *UserMigrationOptions) (*UserMigration, *Response, error) {
u := "user/migrations"
body := &startUserMigration{Repositories: repos}
if opt != nil {
body.LockRepositories = Bool(opt.LockRepositories)
body.ExcludeAttachments = Bool(opt.ExcludeAttachments)
if opts != nil {
body.LockRepositories = Bool(opts.LockRepositories)
body.ExcludeAttachments = Bool(opts.ExcludeAttachments)
}
req, err := s.client.NewRequest("POST", u, body)
@ -96,7 +96,7 @@ func (s *MigrationService) StartUserMigration(ctx context.Context, repos []strin
// ListUserMigrations lists the most recent migrations.
//
// GitHub API docs: https://developer.github.com/v3/migrations/users/#get-a-list-of-user-migrations
// GitHub API docs: https://developer.github.com/v3/migrations/users/#list-user-migrations
func (s *MigrationService) ListUserMigrations(ctx context.Context) ([]*UserMigration, *Response, error) {
u := "user/migrations"
@ -120,7 +120,7 @@ func (s *MigrationService) ListUserMigrations(ctx context.Context) ([]*UserMigra
// 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
// GitHub API docs: https://developer.github.com/v3/migrations/users/#get-a-user-migration-status
func (s *MigrationService) UserMigrationStatus(ctx context.Context, id int64) (*UserMigration, *Response, error) {
u := fmt.Sprintf("user/migrations/%v", id)

View File

@ -40,14 +40,14 @@ type markdownRequest struct {
// 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) {
func (c *Client) Markdown(ctx context.Context, text string, opts *MarkdownOptions) (string, *Response, error) {
request := &markdownRequest{Text: String(text)}
if opt != nil {
if opt.Mode != "" {
request.Mode = String(opt.Mode)
if opts != nil {
if opts.Mode != "" {
request.Mode = String(opts.Mode)
}
if opt.Context != "" {
request.Context = String(opt.Context)
if opts.Context != "" {
request.Context = String(opts.Context)
}
}

View File

@ -29,6 +29,7 @@ type Organization struct {
Blog *string `json:"blog,omitempty"`
Location *string `json:"location,omitempty"`
Email *string `json:"email,omitempty"`
TwitterUsername *string `json:"twitter_username,omitempty"`
Description *string `json:"description,omitempty"`
PublicRepos *int `json:"public_repos,omitempty"`
PublicGists *int `json:"public_gists,omitempty"`
@ -45,6 +46,9 @@ type Organization struct {
Type *string `json:"type,omitempty"`
Plan *Plan `json:"plan,omitempty"`
TwoFactorRequirementEnabled *bool `json:"two_factor_requirement_enabled,omitempty"`
IsVerified *bool `json:"is_verified,omitempty"`
HasOrganizationProjects *bool `json:"has_organization_projects,omitempty"`
HasRepositoryProjects *bool `json:"has_repository_projects,omitempty"`
// DefaultRepoPermission can be one of: "read", "write", "admin", or "none". (Default: "read").
// It is only used in OrganizationsService.Edit.
@ -56,6 +60,19 @@ type Organization struct {
// MembersCanCreateRepos default value is true and is only used in Organizations.Edit.
MembersCanCreateRepos *bool `json:"members_can_create_repositories,omitempty"`
// https://developer.github.com/changes/2019-12-03-internal-visibility-changes/#rest-v3-api
MembersCanCreatePublicRepos *bool `json:"members_can_create_public_repositories,omitempty"`
MembersCanCreatePrivateRepos *bool `json:"members_can_create_private_repositories,omitempty"`
MembersCanCreateInternalRepos *bool `json:"members_can_create_internal_repositories,omitempty"`
// MembersAllowedRepositoryCreationType denotes if organization members can create repositories
// and the type of repositories they can create. Possible values are: "all", "private", or "none".
//
// Deprecated: Use MembersCanCreatePublicRepos, MembersCanCreatePrivateRepos, MembersCanCreateInternalRepos
// instead. The new fields overrides the existing MembersAllowedRepositoryCreationType during 'edit'
// operation and does not consider 'internal' repositories during 'get' operation
MembersAllowedRepositoryCreationType *string `json:"members_allowed_repository_creation_type,omitempty"`
// API URLs
URL *string `json:"url,omitempty"`
EventsURL *string `json:"events_url,omitempty"`
@ -66,6 +83,12 @@ type Organization struct {
ReposURL *string `json:"repos_url,omitempty"`
}
// OrganizationInstallations represents GitHub app installations for an organization.
type OrganizationInstallations struct {
TotalCount *int `json:"total_count,omitempty"`
Installations []*Installation `json:"installations,omitempty"`
}
func (o Organization) String() string {
return Stringify(o)
}
@ -76,6 +99,8 @@ type Plan struct {
Space *int `json:"space,omitempty"`
Collaborators *int `json:"collaborators,omitempty"`
PrivateRepos *int `json:"private_repos,omitempty"`
FilledSeats *int `json:"filled_seats,omitempty"`
Seats *int `json:"seats,omitempty"`
}
func (p Plan) String() string {
@ -100,9 +125,9 @@ type OrganizationsListOptions struct {
// 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)
// GitHub API docs: https://developer.github.com/v3/orgs/#list-organizations
func (s *OrganizationsService) ListAll(ctx context.Context, opts *OrganizationsListOptions) ([]*Organization, *Response, error) {
u, err := addOptions("organizations", opts)
if err != nil {
return nil, nil, err
}
@ -123,15 +148,16 @@ func (s *OrganizationsService) ListAll(ctx context.Context, opt *OrganizationsLi
// 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) {
// GitHub API docs: https://developer.github.com/v3/orgs/#oauth-scope-requirements
// GitHub API docs: https://developer.github.com/v3/orgs/#list-organizations-for-a-user
func (s *OrganizationsService) List(ctx context.Context, user string, opts *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)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -160,6 +186,9 @@ func (s *OrganizationsService) Get(ctx context.Context, org string) (*Organizati
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeMemberAllowedRepoCreationTypePreview)
organization := new(Organization)
resp, err := s.client.Do(ctx, req, organization)
if err != nil {
@ -190,7 +219,7 @@ func (s *OrganizationsService) GetByID(ctx context.Context, id int64) (*Organiza
// Edit an organization.
//
// GitHub API docs: https://developer.github.com/v3/orgs/#edit-an-organization
// GitHub API docs: https://developer.github.com/v3/orgs/#members_can_create_repositories
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)
@ -198,6 +227,9 @@ func (s *OrganizationsService) Edit(ctx context.Context, name string, org *Organ
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeMemberAllowedRepoCreationTypePreview)
o := new(Organization)
resp, err := s.client.Do(ctx, req, o)
if err != nil {
@ -206,3 +238,31 @@ func (s *OrganizationsService) Edit(ctx context.Context, name string, org *Organ
return o, resp, nil
}
// ListInstallations lists installations for an organization.
//
// GitHub API docs: https://developer.github.com/v3/orgs/#list-app-installations-for-an-organization
func (s *OrganizationsService) ListInstallations(ctx context.Context, org string, opts *ListOptions) (*OrganizationInstallations, *Response, error) {
u := fmt.Sprintf("orgs/%v/installations", org)
u, err := addOptions(u, opts)
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)
result := new(OrganizationInstallations)
resp, err := s.client.Do(ctx, req, result)
if err != nil {
return nil, resp, err
}
return result, resp, nil
}

View File

@ -12,10 +12,10 @@ import (
// 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) {
// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#list-organization-webhooks
func (s *OrganizationsService) ListHooks(ctx context.Context, org string, opts *ListOptions) ([]*Hook, *Response, error) {
u := fmt.Sprintf("orgs/%v/hooks", org)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -36,7 +36,7 @@ func (s *OrganizationsService) ListHooks(ctx context.Context, org string, opt *L
// GetHook returns a single specified Hook.
//
// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#get-single-hook
// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#get-an-organization-webhook
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)
@ -54,11 +54,12 @@ func (s *OrganizationsService) GetHook(ctx context.Context, org string, id int64
// 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
// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#create-an-organization-webhook
func (s *OrganizationsService) CreateHook(ctx context.Context, org string, hook *Hook) (*Hook, *Response, error) {
u := fmt.Sprintf("orgs/%v/hooks", org)
hookReq := &createHookRequest{
Name: "web",
Events: hook.Events,
Active: hook.Active,
Config: hook.Config,
@ -80,7 +81,7 @@ func (s *OrganizationsService) CreateHook(ctx context.Context, org string, hook
// EditHook updates a specified Hook.
//
// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#edit-a-hook
// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#update-an-organization-webhook
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)
@ -94,7 +95,7 @@ func (s *OrganizationsService) EditHook(ctx context.Context, org string, id int6
// PingHook triggers a 'ping' event to be sent to the Hook.
//
// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#ping-a-hook
// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#ping-an-organization-webhook
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)
@ -106,7 +107,7 @@ func (s *OrganizationsService) PingHook(ctx context.Context, org string, id int6
// DeleteHook deletes a specified Hook.
//
// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#delete-a-hook
// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#delete-an-organization-webhook
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)

View File

@ -71,15 +71,16 @@ type ListMembersOptions struct {
// 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) {
// GitHub API docs: https://developer.github.com/v3/orgs/members/#list-organization-members
// GitHub API docs: https://developer.github.com/v3/orgs/members/#list-public-organization-members
func (s *OrganizationsService) ListMembers(ctx context.Context, org string, opts *ListMembersOptions) ([]*User, *Response, error) {
var u string
if opt != nil && opt.PublicOnly {
if opts != nil && opts.PublicOnly {
u = fmt.Sprintf("orgs/%v/public_members", org)
} else {
u = fmt.Sprintf("orgs/%v/members", org)
}
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -100,7 +101,7 @@ func (s *OrganizationsService) ListMembers(ctx context.Context, org string, opt
// IsMember checks if a user is a member of an organization.
//
// GitHub API docs: https://developer.github.com/v3/orgs/members/#check-membership
// GitHub API docs: https://developer.github.com/v3/orgs/members/#check-organization-membership-for-a-user
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)
@ -115,7 +116,7 @@ func (s *OrganizationsService) IsMember(ctx context.Context, org, user string) (
// 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
// GitHub API docs: https://developer.github.com/v3/orgs/members/#check-public-organization-membership-for-a-user
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)
@ -130,7 +131,7 @@ func (s *OrganizationsService) IsPublicMember(ctx context.Context, org, user str
// RemoveMember removes a user from all teams of an organization.
//
// GitHub API docs: https://developer.github.com/v3/orgs/members/#remove-a-member
// GitHub API docs: https://developer.github.com/v3/orgs/members/#remove-an-organization-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)
@ -144,7 +145,7 @@ func (s *OrganizationsService) RemoveMember(ctx context.Context, org, user strin
// 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
// GitHub API docs: https://developer.github.com/v3/orgs/members/#set-public-organization-membership-for-the-authenticated-user
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)
@ -157,7 +158,7 @@ func (s *OrganizationsService) PublicizeMembership(ctx context.Context, org, use
// ConcealMembership conceals a user's membership in an organization.
//
// GitHub API docs: https://developer.github.com/v3/orgs/members/#conceal-a-users-membership
// GitHub API docs: https://developer.github.com/v3/orgs/members/#remove-public-organization-membership-for-the-authenticated-user
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)
@ -180,10 +181,10 @@ type ListOrgMembershipsOptions struct {
// 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) {
// GitHub API docs: https://developer.github.com/v3/orgs/members/#list-organization-memberships-for-the-authenticated-user
func (s *OrganizationsService) ListOrgMemberships(ctx context.Context, opts *ListOrgMembershipsOptions) ([]*Membership, *Response, error) {
u := "user/memberships/orgs"
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -206,9 +207,8 @@ func (s *OrganizationsService) ListOrgMemberships(ctx context.Context, opt *List
// 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
// GitHub API docs: https://developer.github.com/v3/orgs/members/#get-an-organization-membership-for-the-authenticated-user
// GitHub API docs: https://developer.github.com/v3/orgs/members/#get-organization-membership-for-a-user
func (s *OrganizationsService) GetOrgMembership(ctx context.Context, user, org string) (*Membership, *Response, error) {
var u string
if user != "" {
@ -235,8 +235,8 @@ func (s *OrganizationsService) GetOrgMembership(ctx context.Context, user, org s
// 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
// GitHub API docs: https://developer.github.com/v3/orgs/members/#update-an-organization-membership-for-the-authenticated-user
// GitHub API docs: https://developer.github.com/v3/orgs/members/#set-organization-membership-for-a-user
func (s *OrganizationsService) EditOrgMembership(ctx context.Context, user, org string, membership *Membership) (*Membership, *Response, error) {
var u, method string
if user != "" {
@ -264,7 +264,7 @@ func (s *OrganizationsService) EditOrgMembership(ctx context.Context, user, org
// 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
// GitHub API docs: https://developer.github.com/v3/orgs/members/#remove-organization-membership-for-a-user
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)
@ -278,9 +278,9 @@ func (s *OrganizationsService) RemoveOrgMembership(ctx context.Context, user, or
// 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) {
func (s *OrganizationsService) ListPendingOrgInvitations(ctx context.Context, org string, opts *ListOptions) ([]*Invitation, *Response, error) {
u := fmt.Sprintf("orgs/%v/invitations", org)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -322,18 +322,15 @@ type CreateOrgInvitationOptions struct {
// 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) {
// GitHub API docs: https://developer.github.com/v3/orgs/members/#create-an-organization-invitation
func (s *OrganizationsService) CreateOrgInvitation(ctx context.Context, org string, opts *CreateOrgInvitationOptions) (*Invitation, *Response, error) {
u := fmt.Sprintf("orgs/%v/invitations", org)
req, err := s.client.NewRequest("POST", u, opt)
req, err := s.client.NewRequest("POST", u, opts)
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 {
@ -346,9 +343,9 @@ func (s *OrganizationsService) CreateOrgInvitation(ctx context.Context, org stri
// 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) {
func (s *OrganizationsService) ListOrgInvitationTeams(ctx context.Context, org, invitationID string, opts *ListOptions) ([]*Team, *Response, error) {
u := fmt.Sprintf("orgs/%v/invitations/%v/teams", org, invitationID)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -358,9 +355,6 @@ func (s *OrganizationsService) ListOrgInvitationTeams(ctx context.Context, org,
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 {

View File

@ -27,10 +27,10 @@ type ListOutsideCollaboratorsOptions struct {
// 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) {
// GitHub API docs: https://developer.github.com/v3/orgs/outside_collaborators/#list-outside-collaborators-for-an-organization
func (s *OrganizationsService) ListOutsideCollaborators(ctx context.Context, org string, opts *ListOutsideCollaboratorsOptions) ([]*User, *Response, error) {
u := fmt.Sprintf("orgs/%v/outside_collaborators", org)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -52,7 +52,7 @@ func (s *OrganizationsService) ListOutsideCollaborators(ctx context.Context, org
// 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
// GitHub API docs: https://developer.github.com/v3/orgs/outside_collaborators/#remove-outside-collaborator-from-an-organization
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)
@ -69,7 +69,7 @@ func (s *OrganizationsService) RemoveOutsideCollaborator(ctx context.Context, or
// 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
// GitHub API docs: https://developer.github.com/v3/orgs/outside_collaborators/#convert-an-organization-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)

View File

@ -13,9 +13,9 @@ import (
// 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) {
func (s *OrganizationsService) ListProjects(ctx context.Context, org string, opts *ProjectListOptions) ([]*Project, *Response, error) {
u := fmt.Sprintf("orgs/%v/projects", org)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -40,9 +40,9 @@ func (s *OrganizationsService) ListProjects(ctx context.Context, org string, opt
// 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) {
func (s *OrganizationsService) CreateProject(ctx context.Context, org string, opts *ProjectOptions) (*Project, *Response, error) {
u := fmt.Sprintf("orgs/%v/projects", org)
req, err := s.client.NewRequest("POST", u, opt)
req, err := s.client.NewRequest("POST", u, opts)
if err != nil {
return nil, nil, err
}

View File

@ -12,10 +12,10 @@ import (
// 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) {
// GitHub API docs: https://developer.github.com/v3/orgs/blocking/#list-users-blocked-by-an-organization
func (s *OrganizationsService) ListBlockedUsers(ctx context.Context, org string, opts *ListOptions) ([]*User, *Response, error) {
u := fmt.Sprintf("orgs/%v/blocks", org)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -39,7 +39,7 @@ func (s *OrganizationsService) ListBlockedUsers(ctx context.Context, org string,
// 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
// GitHub API docs: https://developer.github.com/v3/orgs/blocking/#check-if-a-user-is-blocked-by-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)
@ -58,7 +58,7 @@ func (s *OrganizationsService) IsBlocked(ctx context.Context, org string, user s
// BlockUser blocks specified user from an organization.
//
// GitHub API docs: https://developer.github.com/v3/orgs/blocking/#block-a-user
// GitHub API docs: https://developer.github.com/v3/orgs/blocking/#block-a-user-from-an-organization
func (s *OrganizationsService) BlockUser(ctx context.Context, org string, user string) (*Response, error) {
u := fmt.Sprintf("orgs/%v/blocks/%v", org, user)
@ -75,7 +75,7 @@ func (s *OrganizationsService) BlockUser(ctx context.Context, org string, user s
// UnblockUser unblocks specified user from an organization.
//
// GitHub API docs: https://developer.github.com/v3/orgs/blocking/#unblock-a-user
// GitHub API docs: https://developer.github.com/v3/orgs/blocking/#unblock-a-user-from-an-organization
func (s *OrganizationsService) UnblockUser(ctx context.Context, org string, user string) (*Response, error) {
u := fmt.Sprintf("orgs/%v/blocks/%v", org, user)

View File

@ -0,0 +1,101 @@
// Copyright 2020 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
// Package represents a GitHub package.
type Package struct {
ID *int64 `json:"id,omitempty"`
Name *string `json:"name,omitempty"`
PackageType *string `json:"package_type,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
Owner *User `json:"owner,omitempty"`
PackageVersion *PackageVersion `json:"package_version,omitempty"`
Registry *PackageRegistry `json:"registry,omitempty"`
}
func (p Package) String() string {
return Stringify(p)
}
// PackageVersion represents a GitHub package version.
type PackageVersion struct {
ID *int64 `json:"id,omitempty"`
Version *string `json:"version,omitempty"`
Summary *string `json:"summary,omitempty"`
Body *string `json:"body,omitempty"`
BodyHTML *string `json:"body_html,omitempty"`
Release *PackageRelease `json:"release,omitempty"`
Manifest *string `json:"manifest,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
TagName *string `json:"tag_name,omitempty"`
TargetCommitish *string `json:"target_commitish,omitempty"`
TargetOID *string `json:"target_oid,omitempty"`
Draft *bool `json:"draft,omitempty"`
Prerelease *bool `json:"prerelease,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
PackageFiles []*PackageFile `json:"package_files,omitempty"`
Author *User `json:"author,omitempty"`
InstallationCommand *string `json:"installation_command,omitempty"`
}
func (pv PackageVersion) String() string {
return Stringify(pv)
}
// PackageRelease represents a GitHub package version release.
type PackageRelease struct {
URL *string `json:"url,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
ID *int64 `json:"id,omitempty"`
TagName *string `json:"tag_name,omitempty"`
TargetCommitish *string `json:"target_commitish,omitempty"`
Name *string `json:"name,omitempty"`
Draft *bool `json:"draft,omitempty"`
Author *User `json:"author,omitempty"`
Prerelease *bool `json:"prerelease,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
PublishedAt *Timestamp `json:"published_at,omitempty"`
}
func (r PackageRelease) String() string {
return Stringify(r)
}
// PackageFile represents a GitHub package version release file.
type PackageFile struct {
DownloadURL *string `json:"download_url,omitempty"`
ID *int64 `json:"id,omitempty"`
Name *string `json:"name,omitempty"`
SHA256 *string `json:"sha256,omitempty"`
SHA1 *string `json:"sha1,omitempty"`
MD5 *string `json:"md5,omitempty"`
ContentType *string `json:"content_type,omitempty"`
State *string `json:"state,omitempty"`
Author *User `json:"author,omitempty"`
Size *int64 `json:"size,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
}
func (pf PackageFile) String() string {
return Stringify(pf)
}
// PackageRegistry represents a GitHub package registry.
type PackageRegistry struct {
AboutURL *string `json:"about_url,omitempty"`
Name *string `json:"name,omitempty"`
Type *string `json:"type,omitempty"`
URL *string `json:"url,omitempty"`
Vendor *string `json:"vendor,omitempty"`
}
func (r PackageRegistry) String() string {
return Stringify(r)
}

View File

@ -89,9 +89,9 @@ type ProjectOptions struct {
// 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) {
func (s *ProjectsService) UpdateProject(ctx context.Context, id int64, opts *ProjectOptions) (*Project, *Response, error) {
u := fmt.Sprintf("projects/%v", id)
req, err := s.client.NewRequest("PATCH", u, opt)
req, err := s.client.NewRequest("PATCH", u, opts)
if err != nil {
return nil, nil, err
}
@ -141,9 +141,9 @@ type ProjectColumn struct {
// 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) {
func (s *ProjectsService) ListProjectColumns(ctx context.Context, projectID int64, opts *ListOptions) ([]*ProjectColumn, *Response, error) {
u := fmt.Sprintf("projects/%v/columns", projectID)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -198,9 +198,9 @@ type ProjectColumnOptions struct {
// 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) {
func (s *ProjectsService) CreateProjectColumn(ctx context.Context, projectID int64, opts *ProjectColumnOptions) (*ProjectColumn, *Response, error) {
u := fmt.Sprintf("projects/%v/columns", projectID)
req, err := s.client.NewRequest("POST", u, opt)
req, err := s.client.NewRequest("POST", u, opts)
if err != nil {
return nil, nil, err
}
@ -220,9 +220,9 @@ func (s *ProjectsService) CreateProjectColumn(ctx context.Context, projectID int
// 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) {
func (s *ProjectsService) UpdateProjectColumn(ctx context.Context, columnID int64, opts *ProjectColumnOptions) (*ProjectColumn, *Response, error) {
u := fmt.Sprintf("projects/columns/%v", columnID)
req, err := s.client.NewRequest("PATCH", u, opt)
req, err := s.client.NewRequest("PATCH", u, opts)
if err != nil {
return nil, nil, err
}
@ -266,9 +266,9 @@ type ProjectColumnMoveOptions struct {
// 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) {
func (s *ProjectsService) MoveProjectColumn(ctx context.Context, columnID int64, opts *ProjectColumnMoveOptions) (*Response, error) {
u := fmt.Sprintf("projects/columns/%v/moves", columnID)
req, err := s.client.NewRequest("POST", u, opt)
req, err := s.client.NewRequest("POST", u, opts)
if err != nil {
return nil, err
}
@ -317,9 +317,9 @@ type ProjectCardListOptions struct {
// 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) {
func (s *ProjectsService) ListProjectCards(ctx context.Context, columnID int64, opts *ProjectCardListOptions) ([]*ProjectCard, *Response, error) {
u := fmt.Sprintf("projects/columns/%v/cards", columnID)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -344,8 +344,8 @@ func (s *ProjectsService) ListProjectCards(ctx context.Context, columnID int64,
// 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)
func (s *ProjectsService) GetProjectCard(ctx context.Context, cardID int64) (*ProjectCard, *Response, error) {
u := fmt.Sprintf("projects/columns/cards/%v", cardID)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
@ -382,9 +382,9 @@ type ProjectCardOptions struct {
// 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) {
func (s *ProjectsService) CreateProjectCard(ctx context.Context, columnID int64, opts *ProjectCardOptions) (*ProjectCard, *Response, error) {
u := fmt.Sprintf("projects/columns/%v/cards", columnID)
req, err := s.client.NewRequest("POST", u, opt)
req, err := s.client.NewRequest("POST", u, opts)
if err != nil {
return nil, nil, err
}
@ -404,9 +404,9 @@ func (s *ProjectsService) CreateProjectCard(ctx context.Context, columnID int64,
// 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) {
func (s *ProjectsService) UpdateProjectCard(ctx context.Context, cardID int64, opts *ProjectCardOptions) (*ProjectCard, *Response, error) {
u := fmt.Sprintf("projects/columns/cards/%v", cardID)
req, err := s.client.NewRequest("PATCH", u, opt)
req, err := s.client.NewRequest("PATCH", u, opts)
if err != nil {
return nil, nil, err
}
@ -454,9 +454,9 @@ type ProjectCardMoveOptions struct {
// 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) {
func (s *ProjectsService) MoveProjectCard(ctx context.Context, cardID int64, opts *ProjectCardMoveOptions) (*Response, error) {
u := fmt.Sprintf("projects/columns/cards/%v/moves", cardID)
req, err := s.client.NewRequest("POST", u, opt)
req, err := s.client.NewRequest("POST", u, opts)
if err != nil {
return nil, err
}
@ -483,10 +483,10 @@ type ProjectCollaboratorOptions struct {
// 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) {
// GitHub API docs: https://developer.github.com/v3/projects/collaborators/#add-project-collaborator
func (s *ProjectsService) AddProjectCollaborator(ctx context.Context, id int64, username string, opts *ProjectCollaboratorOptions) (*Response, error) {
u := fmt.Sprintf("projects/%v/collaborators/%v", id, username)
req, err := s.client.NewRequest("PUT", u, opt)
req, err := s.client.NewRequest("PUT", u, opts)
if err != nil {
return nil, err
}
@ -500,7 +500,7 @@ func (s *ProjectsService) AddProjectCollaborator(ctx context.Context, id int64,
// 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
// GitHub API docs: https://developer.github.com/v3/projects/collaborators/#remove-project-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)
@ -536,10 +536,10 @@ type ListCollaboratorOptions struct {
// 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) {
// GitHub API docs: https://developer.github.com/v3/projects/collaborators/#list-project-collaborators
func (s *ProjectsService) ListProjectCollaborators(ctx context.Context, id int64, opts *ListCollaboratorOptions) ([]*User, *Response, error) {
u := fmt.Sprintf("projects/%v/collaborators", id)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -574,7 +574,7 @@ type ProjectPermissionLevel struct {
// 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
// GitHub API docs: https://developer.github.com/v3/projects/collaborators/#get-project-permission-for-a-user
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)

View File

@ -24,6 +24,7 @@ type PullRequest 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"`
CreatedAt *time.Time `json:"created_at,omitempty"`
@ -38,6 +39,7 @@ type PullRequest struct {
MergeableState *string `json:"mergeable_state,omitempty"`
MergedBy *User `json:"merged_by,omitempty"`
MergeCommitSHA *string `json:"merge_commit_sha,omitempty"`
Rebaseable *bool `json:"rebaseable,omitempty"`
Comments *int `json:"comments,omitempty"`
Commits *int `json:"commits,omitempty"`
Additions *int `json:"additions,omitempty"`
@ -134,9 +136,9 @@ type PullRequestListOptions struct {
// 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) {
func (s *PullRequestsService) List(ctx context.Context, owner string, repo string, opts *PullRequestListOptions) ([]*PullRequest, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/pulls", owner, repo)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -147,7 +149,7 @@ func (s *PullRequestsService) List(ctx context.Context, owner string, repo strin
}
// TODO: remove custom Accept header when this API fully launches.
acceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview, mediaTypeDraftPreview}
acceptHeaders := []string{mediaTypeLockReasonPreview}
req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
var pulls []*PullRequest
@ -159,9 +161,38 @@ func (s *PullRequestsService) List(ctx context.Context, owner string, repo strin
return pulls, resp, nil
}
// ListPullRequestsWithCommit returns pull requests associated with a commit SHA.
//
// The results will include open and closed pull requests.
//
// GitHub API docs: https://developer.github.com/v3/repos/commits/#list-pull-requests-associated-with-a-commit
func (s *PullRequestsService) ListPullRequestsWithCommit(ctx context.Context, owner, repo, sha string, opts *PullRequestListOptions) ([]*PullRequest, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/commits/%v/pulls", owner, repo, sha)
u, err := addOptions(u, opts)
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{mediaTypeListPullsOrBranchesForCommitPreview, mediaTypeLockReasonPreview}
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
// GitHub API docs: https://developer.github.com/v3/pulls/#get-a-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)
@ -170,7 +201,7 @@ func (s *PullRequestsService) Get(ctx context.Context, owner string, repo string
}
// TODO: remove custom Accept header when this API fully launches.
acceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview, mediaTypeDraftPreview}
acceptHeaders := []string{mediaTypeLockReasonPreview}
req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
pull := new(PullRequest)
@ -183,20 +214,22 @@ func (s *PullRequestsService) Get(ctx context.Context, owner string, repo string
}
// 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) {
//
// GitHub API docs: https://developer.github.com/v3/pulls/#get-a-pull-request
func (s *PullRequestsService) GetRaw(ctx context.Context, owner string, repo string, number int, opts 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 {
switch opts.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)
return "", nil, fmt.Errorf("unsupported raw type %d", opts.Type)
}
var buf bytes.Buffer
@ -216,6 +249,7 @@ type NewPullRequest struct {
Body *string `json:"body,omitempty"`
Issue *int `json:"issue,omitempty"`
MaintainerCanModify *bool `json:"maintainer_can_modify,omitempty"`
Draft *bool `json:"draft,omitempty"`
}
// Create a new pull request on the specified repository.
@ -228,9 +262,6 @@ func (s *PullRequestsService) Create(ctx context.Context, owner string, repo str
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 {
@ -240,6 +271,49 @@ func (s *PullRequestsService) Create(ctx context.Context, owner string, repo str
return p, resp, nil
}
// PullRequestBranchUpdateOptions specifies the optional parameters to the
// PullRequestsService.UpdateBranch method.
type PullRequestBranchUpdateOptions struct {
// ExpectedHeadSHA specifies the most recent commit on the pull request's branch.
// Default value is the SHA of the pull request's current HEAD ref.
ExpectedHeadSHA *string `json:"expected_head_sha,omitempty"`
}
// PullRequestBranchUpdateResponse specifies the response of pull request branch update.
type PullRequestBranchUpdateResponse struct {
Message *string `json:"message,omitempty"`
URL *string `json:"url,omitempty"`
}
// UpdateBranch updates the pull request branch with latest upstream changes.
//
// 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 update of the pull request branch 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/pulls/#update-a-pull-request-branch
func (s *PullRequestsService) UpdateBranch(ctx context.Context, owner, repo string, number int, opts *PullRequestBranchUpdateOptions) (*PullRequestBranchUpdateResponse, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/pulls/%d/update-branch", owner, repo, number)
req, err := s.client.NewRequest("PUT", u, opts)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeUpdatePullRequestBranchPreview)
p := new(PullRequestBranchUpdateResponse)
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"`
@ -268,7 +342,10 @@ func (s *PullRequestsService) Edit(ctx context.Context, owner string, repo strin
State: pull.State,
MaintainerCanModify: pull.MaintainerCanModify,
}
if pull.Base != nil {
// avoid updating the base branch when closing the Pull Request
// - otherwise the GitHub API server returns a "Validation Failed" error:
// "Cannot change base branch of closed pull request".
if pull.Base != nil && pull.GetState() != "closed" {
update.Base = pull.Base.Ref
}
@ -278,7 +355,7 @@ func (s *PullRequestsService) Edit(ctx context.Context, owner string, repo strin
}
// TODO: remove custom Accept header when this API fully launches.
acceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
acceptHeaders := []string{mediaTypeLockReasonPreview}
req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
p := new(PullRequest)
@ -293,9 +370,9 @@ func (s *PullRequestsService) Edit(ctx context.Context, owner string, repo strin
// 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) {
func (s *PullRequestsService) ListCommits(ctx context.Context, owner string, repo string, number int, opts *ListOptions) ([]*RepositoryCommit, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/pulls/%d/commits", owner, repo, number)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -317,9 +394,9 @@ func (s *PullRequestsService) ListCommits(ctx context.Context, owner string, rep
// 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) {
func (s *PullRequestsService) ListFiles(ctx context.Context, owner string, repo string, number int, opts *ListOptions) ([]*CommitFile, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/pulls/%d/files", owner, repo, number)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -340,7 +417,7 @@ func (s *PullRequestsService) ListFiles(ctx context.Context, owner string, repo
// 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
// GitHub API docs: https://developer.github.com/v3/pulls/#check-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)
@ -362,7 +439,7 @@ type PullRequestMergeResult struct {
// 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.)
CommitTitle string // Title for the 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.)
@ -370,16 +447,16 @@ type PullRequestOptions struct {
}
type pullRequestMergeRequest struct {
CommitMessage string `json:"commit_message"`
CommitMessage string `json:"commit_message,omitempty"`
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.
// Merge a pull request.
// commitMessage is an extra detail to append to automatic commit message.
//
// GitHub API docs: https://developer.github.com/v3/pulls/#merge-a-pull-request-merge-buttontrade
// GitHub API docs: https://developer.github.com/v3/pulls/#merge-a-pull-request
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)

View File

@ -8,12 +8,14 @@ package github
import (
"context"
"fmt"
"strings"
"time"
)
// PullRequestComment represents a comment left on a pull request.
type PullRequestComment struct {
ID *int64 `json:"id,omitempty"`
NodeID *string `json:"node_id,omitempty"`
InReplyTo *int64 `json:"in_reply_to_id,omitempty"`
Body *string `json:"body,omitempty"`
Path *string `json:"path,omitempty"`
@ -21,6 +23,12 @@ type PullRequestComment struct {
PullRequestReviewID *int64 `json:"pull_request_review_id,omitempty"`
Position *int `json:"position,omitempty"`
OriginalPosition *int `json:"original_position,omitempty"`
StartLine *int `json:"start_line,omitempty"`
Line *int `json:"line,omitempty"`
OriginalLine *int `json:"original_line,omitempty"`
OriginalStartLine *int `json:"original_start_line,omitempty"`
Side *string `json:"side,omitempty"`
StartSide *string `json:"start_side,omitempty"`
CommitID *string `json:"commit_id,omitempty"`
OriginalCommitID *string `json:"original_commit_id,omitempty"`
User *User `json:"user,omitempty"`
@ -58,15 +66,16 @@ type PullRequestListCommentsOptions struct {
// 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) {
// GitHub API docs: https://developer.github.com/v3/pulls/comments/#list-review-comments-on-a-pull-request
// GitHub API docs: https://developer.github.com/v3/pulls/comments/#list-review-comments-in-a-repository
func (s *PullRequestsService) ListComments(ctx context.Context, owner string, repo string, number int, opts *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)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -77,7 +86,8 @@ func (s *PullRequestsService) ListComments(ctx context.Context, owner string, re
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeReactionsPreview)
acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeMultiLineCommentsPreview}
req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
var comments []*PullRequestComment
resp, err := s.client.Do(ctx, req, &comments)
@ -90,7 +100,7 @@ func (s *PullRequestsService) ListComments(ctx context.Context, owner string, re
// GetComment fetches the specified pull request comment.
//
// GitHub API docs: https://developer.github.com/v3/pulls/comments/#get-a-single-comment
// GitHub API docs: https://developer.github.com/v3/pulls/comments/#get-a-review-comment-for-a-pull-request
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)
@ -99,7 +109,8 @@ func (s *PullRequestsService) GetComment(ctx context.Context, owner string, repo
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeReactionsPreview)
acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeMultiLineCommentsPreview}
req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
comment := new(PullRequestComment)
resp, err := s.client.Do(ctx, req, comment)
@ -112,13 +123,16 @@ func (s *PullRequestsService) GetComment(ctx context.Context, owner string, repo
// CreateComment creates a new comment on the specified pull request.
//
// GitHub API docs: https://developer.github.com/v3/pulls/comments/#create-a-comment
// GitHub API docs: https://developer.github.com/v3/pulls/comments/#create-a-review-comment-for-a-pull-request
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
}
// TODO: remove custom Accept headers when their respective API fully launches.
acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeMultiLineCommentsPreview}
req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
c := new(PullRequestComment)
resp, err := s.client.Do(ctx, req, c)
@ -131,7 +145,7 @@ func (s *PullRequestsService) CreateComment(ctx context.Context, owner string, r
// 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
// GitHub API docs: https://developer.github.com/v3/pulls/comments/#create-a-review-comment-for-a-pull-request
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"`
@ -158,7 +172,7 @@ func (s *PullRequestsService) CreateCommentInReplyTo(ctx context.Context, owner
// 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
// GitHub API docs: https://developer.github.com/v3/pulls/comments/#update-a-review-comment-for-a-pull-request
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)
@ -177,7 +191,7 @@ func (s *PullRequestsService) EditComment(ctx context.Context, owner string, rep
// DeleteComment deletes a pull request comment.
//
// GitHub API docs: https://developer.github.com/v3/pulls/comments/#delete-a-comment
// GitHub API docs: https://developer.github.com/v3/pulls/comments/#delete-a-review-comment-for-a-pull-request
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)

View File

@ -12,6 +12,7 @@ import (
// ReviewersRequest specifies users and teams for a pull request review request.
type ReviewersRequest struct {
NodeID *string `json:"node_id,omitempty"`
Reviewers []string `json:"reviewers,omitempty"`
TeamReviewers []string `json:"team_reviewers,omitempty"`
}
@ -24,7 +25,7 @@ type Reviewers struct {
// 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
// GitHub API docs: https://developer.github.com/v3/pulls/review_requests/#request-reviewers-for-a-pull-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)
@ -43,10 +44,10 @@ func (s *PullRequestsService) RequestReviewers(ctx context.Context, owner, repo
// 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) {
// GitHub API docs: https://developer.github.com/v3/pulls/review_requests/#list-requested-reviewers-for-a-pull-request
func (s *PullRequestsService) ListReviewers(ctx context.Context, owner, repo string, number int, opts *ListOptions) (*Reviewers, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/pulls/%d/requested_reviewers", owner, repo, number)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -67,7 +68,7 @@ func (s *PullRequestsService) ListReviewers(ctx context.Context, owner, repo str
// 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
// GitHub API docs: https://developer.github.com/v3/pulls/review_requests/#remove-requested-reviewers-from-a-pull-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)

View File

@ -7,13 +7,17 @@ package github
import (
"context"
"errors"
"fmt"
"time"
)
var ErrMixedCommentStyles = errors.New("cannot use both position and side/line form comments")
// PullRequestReview represents a review of a pull request.
type PullRequestReview struct {
ID *int64 `json:"id,omitempty"`
NodeID *string `json:"node_id,omitempty"`
User *User `json:"user,omitempty"`
Body *string `json:"body,omitempty"`
SubmittedAt *time.Time `json:"submitted_at,omitempty"`
@ -21,6 +25,9 @@ type PullRequestReview struct {
HTMLURL *string `json:"html_url,omitempty"`
PullRequestURL *string `json:"pull_request_url,omitempty"`
State *string `json:"state,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"`
}
func (p PullRequestReview) String() string {
@ -32,6 +39,12 @@ type DraftReviewComment struct {
Path *string `json:"path,omitempty"`
Position *int `json:"position,omitempty"`
Body *string `json:"body,omitempty"`
// The new comfort-fade-preview fields
StartSide *string `json:"start_side,omitempty"`
Side *string `json:"side,omitempty"`
StartLine *int `json:"start_line,omitempty"`
Line *int `json:"line,omitempty"`
}
func (c DraftReviewComment) String() string {
@ -40,6 +53,7 @@ func (c DraftReviewComment) String() string {
// PullRequestReviewRequest represents a request to create a review.
type PullRequestReviewRequest struct {
NodeID *string `json:"node_id,omitempty"`
CommitID *string `json:"commit_id,omitempty"`
Body *string `json:"body,omitempty"`
Event *string `json:"event,omitempty"`
@ -50,6 +64,32 @@ func (r PullRequestReviewRequest) String() string {
return Stringify(r)
}
func (r PullRequestReviewRequest) isComfortFadePreview() (bool, error) {
var isCF *bool
for _, comment := range r.Comments {
if comment == nil {
continue
}
hasPos := comment.Position != nil
hasComfortFade := (comment.StartSide != nil) || (comment.Side != nil) ||
(comment.StartLine != nil) || (comment.Line != nil)
switch {
case hasPos && hasComfortFade:
return false, ErrMixedCommentStyles
case hasPos && isCF != nil && *isCF:
return false, ErrMixedCommentStyles
case hasComfortFade && isCF != nil && !*isCF:
return false, ErrMixedCommentStyles
}
isCF = &hasComfortFade
}
if isCF != nil {
return *isCF, nil
}
return false, nil
}
// PullRequestReviewDismissalRequest represents a request to dismiss a review.
type PullRequestReviewDismissalRequest struct {
Message *string `json:"message,omitempty"`
@ -65,10 +105,10 @@ func (r PullRequestReviewDismissalRequest) String() string {
// 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) {
// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#list-reviews-for-a-pull-request
func (s *PullRequestsService) ListReviews(ctx context.Context, owner, repo string, number int, opts *ListOptions) ([]*PullRequestReview, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews", owner, repo, number)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -93,7 +133,7 @@ func (s *PullRequestsService) ListReviews(ctx context.Context, owner, repo strin
// 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
// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#get-a-review-for-a-pull-request
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)
@ -117,7 +157,7 @@ func (s *PullRequestsService) GetReview(ctx context.Context, owner, repo string,
// 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
// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#delete-a-pending-review-for-a-pull-request
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)
@ -141,10 +181,10 @@ 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-comments-for-a-single-review
func (s *PullRequestsService) ListReviewComments(ctx context.Context, owner, repo string, number int, reviewID int64, opt *ListOptions) ([]*PullRequestComment, *Response, error) {
// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#list-comments-for-a-pull-request-review
func (s *PullRequestsService) ListReviewComments(ctx context.Context, owner, repo string, number int, reviewID int64, opts *ListOptions) ([]*PullRequestComment, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d/comments", owner, repo, number, reviewID)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -169,7 +209,39 @@ func (s *PullRequestsService) ListReviewComments(ctx context.Context, owner, rep
// 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
// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#create-a-review-for-a-pull-request
//
// In order to use multi-line comments, you must use the "comfort fade" preview.
// This replaces the use of the "Position" field in comments with 4 new fields:
// [Start]Side, and [Start]Line.
// These new fields must be used for ALL comments (including single-line),
// with the following restrictions (empirically observed, so subject to change).
//
// For single-line "comfort fade" comments, you must use:
//
// Path: &path, // as before
// Body: &body, // as before
// Side: &"RIGHT" (or "LEFT")
// Line: &123, // NOT THE SAME AS POSITION, this is an actual line number.
//
// If StartSide or StartLine is used with single-line comments, a 422 is returned.
//
// For multi-line "comfort fade" comments, you must use:
//
// Path: &path, // as before
// Body: &body, // as before
// StartSide: &"RIGHT" (or "LEFT")
// Side: &"RIGHT" (or "LEFT")
// StartLine: &120,
// Line: &125,
//
// Suggested edits are made by commenting on the lines to replace, and including the
// suggested edit in a block like this (it may be surrounded in non-suggestion markdown):
//
// ```suggestion
// Use this instead.
// It is waaaaaay better.
// ```
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)
@ -178,6 +250,15 @@ func (s *PullRequestsService) CreateReview(ctx context.Context, owner, repo stri
return nil, nil, err
}
// Detect which style of review comment is being used.
if isCF, err := review.isComfortFadePreview(); err != nil {
return nil, nil, err
} else if isCF {
// If the review comments are using the comfort fade preview fields,
// then pass the comfort fade header.
req.Header.Set("Accept", mediaTypeMultiLineCommentsPreview)
}
r := new(PullRequestReview)
resp, err := s.client.Do(ctx, req, r)
if err != nil {
@ -187,13 +268,36 @@ func (s *PullRequestsService) CreateReview(ctx context.Context, owner, repo stri
return r, resp, nil
}
// UpdateReview updates the review summary on the specified pull request.
//
// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#update-a-review-for-a-pull-request
func (s *PullRequestsService) UpdateReview(ctx context.Context, owner, repo string, number int, reviewID int64, body string) (*PullRequestReview, *Response, error) {
opts := &struct {
Body string `json:"body"`
}{Body: body}
u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d", owner, repo, number, reviewID)
req, err := s.client.NewRequest("PUT", u, opts)
if err != nil {
return nil, nil, err
}
review := &PullRequestReview{}
resp, err := s.client.Do(ctx, req, review)
if err != nil {
return nil, resp, err
}
return review, 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
// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#submit-a-review-for-a-pull-request
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)
@ -217,7 +321,7 @@ func (s *PullRequestsService) SubmitReview(ctx context.Context, owner, repo stri
// 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
// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#dismiss-a-review-for-a-pull-request
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)

View File

@ -8,6 +8,7 @@ package github
import (
"context"
"fmt"
"net/http"
)
// ReactionsService provides access to the reactions-related functions in the
@ -44,12 +45,23 @@ func (r Reaction) String() string {
return Stringify(r)
}
// ListCommentReactionOptions specifies the optional parameters to the
// ReactionsService.ListCommentReactions method.
type ListCommentReactionOptions struct {
// Content restricts the returned comment reactions to only those with the given type.
// Omit this parameter to list all reactions to a commit comment.
// Possible values are: "+1", "-1", "laugh", "confused", "heart", "hooray", "rocket", or "eyes".
Content string `url:"content,omitempty"`
ListOptions
}
// 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) {
func (s *ReactionsService) ListCommentReactions(ctx context.Context, owner, repo string, id int64, opts *ListCommentReactionOptions) ([]*Reaction, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/comments/%v/reactions", owner, repo, id)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -77,7 +89,7 @@ func (s *ReactionsService) ListCommentReactions(ctx context.Context, owner, repo
// 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) {
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)}
@ -98,12 +110,30 @@ func (s ReactionsService) CreateCommentReaction(ctx context.Context, owner, repo
return m, resp, nil
}
// DeleteCommentReaction deletes the reaction for a commit comment.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#delete-a-commit-comment-reaction
func (s *ReactionsService) DeleteCommentReaction(ctx context.Context, owner, repo string, commentID, reactionID int64) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/comments/%v/reactions/%v", owner, repo, commentID, reactionID)
return s.deleteReaction(ctx, u)
}
// DeleteCommentReactionByID deletes the reaction for a commit comment by repository ID.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#delete-a-commit-comment-reaction
func (s *ReactionsService) DeleteCommentReactionByID(ctx context.Context, repoID, commentID, reactionID int64) (*Response, error) {
u := fmt.Sprintf("repositories/%v/comments/%v/reactions/%v", repoID, commentID, reactionID)
return s.deleteReaction(ctx, u)
}
// 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) {
func (s *ReactionsService) ListIssueReactions(ctx context.Context, owner, repo string, number int, opts *ListOptions) ([]*Reaction, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/%v/reactions", owner, repo, number)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -131,7 +161,7 @@ func (s *ReactionsService) ListIssueReactions(ctx context.Context, owner, repo s
// 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) {
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)}
@ -152,12 +182,30 @@ func (s ReactionsService) CreateIssueReaction(ctx context.Context, owner, repo s
return m, resp, nil
}
// DeleteIssueReaction deletes the reaction to an issue.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#delete-an-issue-reaction
func (s *ReactionsService) DeleteIssueReaction(ctx context.Context, owner, repo string, issueNumber int, reactionID int64) (*Response, error) {
url := fmt.Sprintf("repos/%v/%v/issues/%v/reactions/%v", owner, repo, issueNumber, reactionID)
return s.deleteReaction(ctx, url)
}
// DeleteIssueReactionByID deletes the reaction to an issue by repository ID.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#delete-an-issue-reaction
func (s *ReactionsService) DeleteIssueReactionByID(ctx context.Context, repoID, issueNumber int, reactionID int64) (*Response, error) {
url := fmt.Sprintf("repositories/%v/issues/%v/reactions/%v", repoID, issueNumber, reactionID)
return s.deleteReaction(ctx, url)
}
// 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) {
func (s *ReactionsService) ListIssueCommentReactions(ctx context.Context, owner, repo string, id int64, opts *ListOptions) ([]*Reaction, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/comments/%v/reactions", owner, repo, id)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -185,7 +233,7 @@ func (s *ReactionsService) ListIssueCommentReactions(ctx context.Context, owner,
// 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) {
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)}
@ -206,12 +254,30 @@ func (s ReactionsService) CreateIssueCommentReaction(ctx context.Context, owner,
return m, resp, nil
}
// DeleteIssueCommentReaction deletes the reaction to an issue comment.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#delete-an-issue-comment-reaction
func (s *ReactionsService) DeleteIssueCommentReaction(ctx context.Context, owner, repo string, commentID, reactionID int64) (*Response, error) {
url := fmt.Sprintf("repos/%v/%v/issues/comments/%v/reactions/%v", owner, repo, commentID, reactionID)
return s.deleteReaction(ctx, url)
}
// DeleteIssueCommentReactionByID deletes the reaction to an issue comment by repository ID.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#delete-an-issue-comment-reaction
func (s *ReactionsService) DeleteIssueCommentReactionByID(ctx context.Context, repoID, commentID, reactionID int64) (*Response, error) {
url := fmt.Sprintf("repositories/%v/issues/comments/%v/reactions/%v", repoID, commentID, reactionID)
return s.deleteReaction(ctx, url)
}
// 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) {
// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-pull-request-review-comment
func (s *ReactionsService) ListPullRequestCommentReactions(ctx context.Context, owner, repo string, id int64, opts *ListOptions) ([]*Reaction, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/pulls/comments/%v/reactions", owner, repo, id)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -238,8 +304,8 @@ func (s *ReactionsService) ListPullRequestCommentReactions(ctx context.Context,
// 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) {
// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-pull-request-review-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)}
@ -260,12 +326,30 @@ func (s ReactionsService) CreatePullRequestCommentReaction(ctx context.Context,
return m, resp, nil
}
// DeletePullRequestCommentReaction deletes the reaction to a pull request review comment.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#delete-a-pull-request-comment-reaction
func (s *ReactionsService) DeletePullRequestCommentReaction(ctx context.Context, owner, repo string, commentID, reactionID int64) (*Response, error) {
url := fmt.Sprintf("repos/%v/%v/pulls/comments/%v/reactions/%v", owner, repo, commentID, reactionID)
return s.deleteReaction(ctx, url)
}
// DeletePullRequestCommentReactionByID deletes the reaction to a pull request review comment by repository ID.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#delete-a-pull-request-comment-reaction
func (s *ReactionsService) DeletePullRequestCommentReactionByID(ctx context.Context, repoID, commentID, reactionID int64) (*Response, error) {
url := fmt.Sprintf("repositories/%v/pulls/comments/%v/reactions/%v", repoID, commentID, reactionID)
return s.deleteReaction(ctx, url)
}
// 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) {
// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-team-discussion-legacy
func (s *ReactionsService) ListTeamDiscussionReactions(ctx context.Context, teamID int64, discussionNumber int, opts *ListOptions) ([]*Reaction, *Response, error) {
u := fmt.Sprintf("teams/%v/discussions/%v/reactions", teamID, discussionNumber)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -289,7 +373,7 @@ func (s *ReactionsService) ListTeamDiscussionReactions(ctx context.Context, team
// 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
// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-team-discussion-legacy
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)
@ -310,12 +394,30 @@ func (s *ReactionsService) CreateTeamDiscussionReaction(ctx context.Context, tea
return m, resp, nil
}
// DeleteTeamDiscussionReaction deletes the reaction to a team discussion.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#delete-team-discussion-reaction
func (s *ReactionsService) DeleteTeamDiscussionReaction(ctx context.Context, org, teamSlug string, discussionNumber int, reactionID int64) (*Response, error) {
url := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/reactions/%v", org, teamSlug, discussionNumber, reactionID)
return s.deleteReaction(ctx, url)
}
// DeleteTeamDiscussionReactionByOrgIDAndTeamID deletes the reaction to a team discussion by organization ID and team ID.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#delete-team-discussion-reaction
func (s *ReactionsService) DeleteTeamDiscussionReactionByOrgIDAndTeamID(ctx context.Context, orgID, teamID, discussionNumber int, reactionID int64) (*Response, error) {
url := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/reactions/%v", orgID, teamID, discussionNumber, reactionID)
return s.deleteReaction(ctx, url)
}
// 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) {
// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-team-discussion-comment-legacy
func (s *ReactionsService) ListTeamDiscussionCommentReactions(ctx context.Context, teamID int64, discussionNumber, commentNumber int, opts *ListOptions) ([]*Reaction, *Response, error) {
u := fmt.Sprintf("teams/%v/discussions/%v/comments/%v/reactions", teamID, discussionNumber, commentNumber)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -338,7 +440,7 @@ func (s *ReactionsService) ListTeamDiscussionCommentReactions(ctx context.Contex
// 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
// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-team-discussion-comment-legacy
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)
@ -359,18 +461,31 @@ func (s *ReactionsService) CreateTeamDiscussionCommentReaction(ctx context.Conte
return m, resp, nil
}
// DeleteReaction deletes a reaction.
// DeleteTeamDiscussionCommentReaction deletes the reaction to a team discussion comment.
//
// 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)
// GitHub API docs: https://developer.github.com/v3/reactions/#delete-team-discussion-comment-reaction
func (s *ReactionsService) DeleteTeamDiscussionCommentReaction(ctx context.Context, org, teamSlug string, discussionNumber, commentNumber int, reactionID int64) (*Response, error) {
url := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/comments/%v/reactions/%v", org, teamSlug, discussionNumber, commentNumber, reactionID)
req, err := s.client.NewRequest("DELETE", u, nil)
return s.deleteReaction(ctx, url)
}
// DeleteTeamDiscussionCommentReactionByOrgIDAndTeamID deletes the reaction to a team discussion comment by organization ID and team ID.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#delete-team-discussion-comment-reaction
func (s *ReactionsService) DeleteTeamDiscussionCommentReactionByOrgIDAndTeamID(ctx context.Context, orgID, teamID, discussionNumber, commentNumber int, reactionID int64) (*Response, error) {
url := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/comments/%v/reactions/%v", orgID, teamID, discussionNumber, commentNumber, reactionID)
return s.deleteReaction(ctx, url)
}
func (s *ReactionsService) deleteReaction(ctx context.Context, url string) (*Response, error) {
req, err := s.client.NewRequest(http.MethodDelete, url, nil)
if err != nil {
return nil, err
}
// TODO: remove custom Accept header when this API fully launches.
// TODO: remove custom Accept headers when APIs fully launch.
req.Header.Set("Accept", mediaTypeReactionsPreview)
return s.client.Do(ctx, req, nil)

View File

@ -7,6 +7,7 @@ package github
import (
"context"
"encoding/json"
"fmt"
"strings"
)
@ -19,44 +20,47 @@ type RepositoriesService service
// Repository represents a GitHub repository.
type Repository struct {
ID *int64 `json:"id,omitempty"`
NodeID *string `json:"node_id,omitempty"`
Owner *User `json:"owner,omitempty"`
Name *string `json:"name,omitempty"`
FullName *string `json:"full_name,omitempty"`
Description *string `json:"description,omitempty"`
Homepage *string `json:"homepage,omitempty"`
CodeOfConduct *CodeOfConduct `json:"code_of_conduct,omitempty"`
DefaultBranch *string `json:"default_branch,omitempty"`
MasterBranch *string `json:"master_branch,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
PushedAt *Timestamp `json:"pushed_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
CloneURL *string `json:"clone_url,omitempty"`
GitURL *string `json:"git_url,omitempty"`
MirrorURL *string `json:"mirror_url,omitempty"`
SSHURL *string `json:"ssh_url,omitempty"`
SVNURL *string `json:"svn_url,omitempty"`
Language *string `json:"language,omitempty"`
Fork *bool `json:"fork,omitempty"`
ForksCount *int `json:"forks_count,omitempty"`
NetworkCount *int `json:"network_count,omitempty"`
OpenIssuesCount *int `json:"open_issues_count,omitempty"`
StargazersCount *int `json:"stargazers_count,omitempty"`
SubscribersCount *int `json:"subscribers_count,omitempty"`
WatchersCount *int `json:"watchers_count,omitempty"`
Size *int `json:"size,omitempty"`
AutoInit *bool `json:"auto_init,omitempty"`
Parent *Repository `json:"parent,omitempty"`
Source *Repository `json:"source,omitempty"`
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"`
ID *int64 `json:"id,omitempty"`
NodeID *string `json:"node_id,omitempty"`
Owner *User `json:"owner,omitempty"`
Name *string `json:"name,omitempty"`
FullName *string `json:"full_name,omitempty"`
Description *string `json:"description,omitempty"`
Homepage *string `json:"homepage,omitempty"`
CodeOfConduct *CodeOfConduct `json:"code_of_conduct,omitempty"`
DefaultBranch *string `json:"default_branch,omitempty"`
MasterBranch *string `json:"master_branch,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
PushedAt *Timestamp `json:"pushed_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
CloneURL *string `json:"clone_url,omitempty"`
GitURL *string `json:"git_url,omitempty"`
MirrorURL *string `json:"mirror_url,omitempty"`
SSHURL *string `json:"ssh_url,omitempty"`
SVNURL *string `json:"svn_url,omitempty"`
Language *string `json:"language,omitempty"`
Fork *bool `json:"fork,omitempty"`
ForksCount *int `json:"forks_count,omitempty"`
NetworkCount *int `json:"network_count,omitempty"`
OpenIssuesCount *int `json:"open_issues_count,omitempty"`
StargazersCount *int `json:"stargazers_count,omitempty"`
SubscribersCount *int `json:"subscribers_count,omitempty"`
WatchersCount *int `json:"watchers_count,omitempty"`
Size *int `json:"size,omitempty"`
AutoInit *bool `json:"auto_init,omitempty"`
Parent *Repository `json:"parent,omitempty"`
Source *Repository `json:"source,omitempty"`
TemplateRepository *Repository `json:"template_repository,omitempty"`
Organization *Organization `json:"organization,omitempty"`
Permissions *map[string]bool `json:"permissions,omitempty"`
AllowRebaseMerge *bool `json:"allow_rebase_merge,omitempty"`
AllowSquashMerge *bool `json:"allow_squash_merge,omitempty"`
AllowMergeCommit *bool `json:"allow_merge_commit,omitempty"`
DeleteBranchOnMerge *bool `json:"delete_branch_on_merge,omitempty"`
Topics []string `json:"topics,omitempty"`
Archived *bool `json:"archived,omitempty"`
Disabled *bool `json:"disabled,omitempty"`
// Only provided when using RepositoriesService.Get while in preview
License *License `json:"license,omitempty"`
@ -68,6 +72,7 @@ type Repository struct {
HasPages *bool `json:"has_pages,omitempty"`
HasProjects *bool `json:"has_projects,omitempty"`
HasDownloads *bool `json:"has_downloads,omitempty"`
IsTemplate *bool `json:"is_template,omitempty"`
LicenseTemplate *string `json:"license_template,omitempty"`
GitignoreTemplate *string `json:"gitignore_template,omitempty"`
@ -115,13 +120,30 @@ type Repository struct {
// 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"`
TextMatches []*TextMatch `json:"text_matches,omitempty"`
// Visibility is only used for Create and Edit endpoints. The visibility field
// overrides the field parameter when both are used.
// Can be one of public, private or internal.
Visibility *string `json:"visibility,omitempty"`
}
func (r Repository) String() string {
return Stringify(r)
}
// BranchListOptions specifies the optional parameters to the
// RepositoriesService.ListBranches method.
type BranchListOptions struct {
// Setting to true returns only protected branches.
// When set to false, only unprotected branches are returned.
// Omitting this parameter returns all branches.
// Default: nil
Protected *bool `url:"protected,omitempty"`
ListOptions
}
// RepositoryListOptions specifies the optional parameters to the
// RepositoriesService.List method.
type RepositoryListOptions struct {
@ -160,15 +182,16 @@ type RepositoryListOptions struct {
// 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) {
// GitHub API docs: https://developer.github.com/v3/repos/#list-repositories-for-a-user
// GitHub API docs: https://developer.github.com/v3/repos/#list-repositories-for-the-authenticated-user
func (s *RepositoriesService) List(ctx context.Context, user string, opts *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)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -198,15 +221,23 @@ type RepositoryListByOrgOptions struct {
// forks, sources, member. Default is "all".
Type string `url:"type,omitempty"`
// How to sort the repository list. Can be one of created, updated, pushed,
// full_name. Default is "created".
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
}
// 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) {
func (s *RepositoriesService) ListByOrg(ctx context.Context, org string, opts *RepositoryListByOrgOptions) ([]*Repository, *Response, error) {
u := fmt.Sprintf("orgs/%v/repos", org)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -238,9 +269,9 @@ type RepositoryListAllOptions struct {
// 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)
// GitHub API docs: https://developer.github.com/v3/repos/#list-public-repositories
func (s *RepositoriesService) ListAll(ctx context.Context, opts *RepositoryListAllOptions) ([]*Repository, *Response, error) {
u, err := addOptions("repositories", opts)
if err != nil {
return nil, nil, err
}
@ -270,20 +301,23 @@ type createRepoRequest struct {
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"`
Private *bool `json:"private,omitempty"`
Visibility *string `json:"visibility,omitempty"`
HasIssues *bool `json:"has_issues,omitempty"`
HasProjects *bool `json:"has_projects,omitempty"`
HasWiki *bool `json:"has_wiki,omitempty"`
IsTemplate *bool `json:"is_template,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"`
AutoInit *bool `json:"auto_init,omitempty"`
GitignoreTemplate *string `json:"gitignore_template,omitempty"`
LicenseTemplate *string `json:"license_template,omitempty"`
AllowSquashMerge *bool `json:"allow_squash_merge,omitempty"`
AllowMergeCommit *bool `json:"allow_merge_commit,omitempty"`
AllowRebaseMerge *bool `json:"allow_rebase_merge,omitempty"`
DeleteBranchOnMerge *bool `json:"delete_branch_on_merge,omitempty"`
}
// Create a new repository. If an organization is specified, the new
@ -293,7 +327,8 @@ type createRepoRequest struct {
// 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
// GitHub API docs: https://developer.github.com/v3/repos/#create-a-repository-for-the-authenticated-user
// GitHub API docs: https://developer.github.com/v3/repos/#create-an-organization-repository
func (s *RepositoriesService) Create(ctx context.Context, org string, repo *Repository) (*Repository, *Response, error) {
var u string
if org != "" {
@ -303,20 +338,23 @@ func (s *RepositoriesService) Create(ctx context.Context, org string, repo *Repo
}
repoReq := &createRepoRequest{
Name: repo.Name,
Description: repo.Description,
Homepage: repo.Homepage,
Private: repo.Private,
HasIssues: repo.HasIssues,
HasProjects: repo.HasProjects,
HasWiki: repo.HasWiki,
TeamID: repo.TeamID,
AutoInit: repo.AutoInit,
GitignoreTemplate: repo.GitignoreTemplate,
LicenseTemplate: repo.LicenseTemplate,
AllowSquashMerge: repo.AllowSquashMerge,
AllowMergeCommit: repo.AllowMergeCommit,
AllowRebaseMerge: repo.AllowRebaseMerge,
Name: repo.Name,
Description: repo.Description,
Homepage: repo.Homepage,
Private: repo.Private,
Visibility: repo.Visibility,
HasIssues: repo.HasIssues,
HasProjects: repo.HasProjects,
HasWiki: repo.HasWiki,
IsTemplate: repo.IsTemplate,
TeamID: repo.TeamID,
AutoInit: repo.AutoInit,
GitignoreTemplate: repo.GitignoreTemplate,
LicenseTemplate: repo.LicenseTemplate,
AllowSquashMerge: repo.AllowSquashMerge,
AllowMergeCommit: repo.AllowMergeCommit,
AllowRebaseMerge: repo.AllowRebaseMerge,
DeleteBranchOnMerge: repo.DeleteBranchOnMerge,
}
req, err := s.client.NewRequest("POST", u, repoReq)
@ -324,6 +362,39 @@ func (s *RepositoriesService) Create(ctx context.Context, org string, repo *Repo
return nil, nil, err
}
acceptHeaders := []string{mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview}
req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
r := new(Repository)
resp, err := s.client.Do(ctx, req, r)
if err != nil {
return nil, resp, err
}
return r, resp, nil
}
// TemplateRepoRequest represents a request to create a repository from a template.
type TemplateRepoRequest struct {
// Name is required when creating a repo.
Name *string `json:"name,omitempty"`
Owner *string `json:"owner,omitempty"`
Description *string `json:"description,omitempty"`
Private *bool `json:"private,omitempty"`
}
// CreateFromTemplate generates a repository from a template.
//
// GitHub API docs: https://developer.github.com/v3/repos/#create-a-repository-using-a-template
func (s *RepositoriesService) CreateFromTemplate(ctx context.Context, templateOwner, templateRepo string, templateRepoReq *TemplateRepoRequest) (*Repository, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/generate", templateOwner, templateRepo)
req, err := s.client.NewRequest("POST", u, templateRepoReq)
if err != nil {
return nil, nil, err
}
req.Header.Set("Accept", mediaTypeRepositoryTemplatePreview)
r := new(Repository)
resp, err := s.client.Do(ctx, req, r)
if err != nil {
@ -335,7 +406,7 @@ func (s *RepositoriesService) Create(ctx context.Context, org string, repo *Repo
// Get fetches a repository.
//
// GitHub API docs: https://developer.github.com/v3/repos/#get
// GitHub API docs: https://developer.github.com/v3/repos/#get-a-repository
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)
@ -345,7 +416,12 @@ 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{mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview}
acceptHeaders := []string{
mediaTypeCodesOfConductPreview,
mediaTypeTopicsPreview,
mediaTypeRepositoryTemplatePreview,
mediaTypeRepositoryVisibilityPreview,
}
req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
repository := new(Repository)
@ -359,7 +435,7 @@ func (s *RepositoriesService) Get(ctx context.Context, owner, repo string) (*Rep
// 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
// GitHub API docs: https://developer.github.com/v3/codes_of_conduct/#get-the-code-of-conduct-for-a-repository
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)
@ -400,7 +476,7 @@ func (s *RepositoriesService) GetByID(ctx context.Context, id int64) (*Repositor
// Edit updates a repository.
//
// GitHub API docs: https://developer.github.com/v3/repos/#edit
// GitHub API docs: https://developer.github.com/v3/repos/#update-a-repository
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)
@ -408,6 +484,8 @@ func (s *RepositoriesService) Edit(ctx context.Context, owner, repo string, repo
return nil, nil, err
}
acceptHeaders := []string{mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview}
req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
r := new(Repository)
resp, err := s.client.Do(ctx, req, r)
if err != nil {
@ -434,6 +512,7 @@ func (s *RepositoriesService) Delete(ctx context.Context, owner, repo string) (*
type Contributor struct {
Login *string `json:"login,omitempty"`
ID *int64 `json:"id,omitempty"`
NodeID *string `json:"node_id,omitempty"`
AvatarURL *string `json:"avatar_url,omitempty"`
GravatarID *string `json:"gravatar_id,omitempty"`
URL *string `json:"url,omitempty"`
@ -461,12 +540,100 @@ type ListContributorsOptions struct {
ListOptions
}
// GetVulnerabilityAlerts checks if vulnerability alerts are enabled for a repository.
//
// GitHub API docs: https://developer.github.com/v3/repos/#check-if-vulnerability-alerts-are-enabled-for-a-repository
func (s *RepositoriesService) GetVulnerabilityAlerts(ctx context.Context, owner, repository string) (bool, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/vulnerability-alerts", owner, repository)
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", mediaTypeRequiredVulnerabilityAlertsPreview)
resp, err := s.client.Do(ctx, req, nil)
vulnerabilityAlertsEnabled, err := parseBoolResponse(err)
return vulnerabilityAlertsEnabled, resp, err
}
// EnableVulnerabilityAlerts enables vulnerability alerts and the dependency graph for a repository.
//
// GitHub API docs: https://developer.github.com/v3/repos/#enable-vulnerability-alerts
func (s *RepositoriesService) EnableVulnerabilityAlerts(ctx context.Context, owner, repository string) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/vulnerability-alerts", owner, repository)
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", mediaTypeRequiredVulnerabilityAlertsPreview)
return s.client.Do(ctx, req, nil)
}
// DisableVulnerabilityAlerts disables vulnerability alerts and the dependency graph for a repository.
//
// GitHub API docs: https://developer.github.com/v3/repos/#disable-vulnerability-alerts
func (s *RepositoriesService) DisableVulnerabilityAlerts(ctx context.Context, owner, repository string) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/vulnerability-alerts", owner, repository)
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", mediaTypeRequiredVulnerabilityAlertsPreview)
return s.client.Do(ctx, req, nil)
}
// EnableAutomatedSecurityFixes enables the automated security fixes for a repository.
//
// GitHub API docs: https://developer.github.com/v3/repos/#enable-automated-security-fixes
func (s *RepositoriesService) EnableAutomatedSecurityFixes(ctx context.Context, owner, repository string) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/automated-security-fixes", owner, repository)
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", mediaTypeRequiredAutomatedSecurityFixesPreview)
return s.client.Do(ctx, req, nil)
}
// DisableAutomatedSecurityFixes disables vulnerability alerts and the dependency graph for a repository.
//
// GitHub API docs: https://developer.github.com/v3/repos/#disable-automated-security-fixes
func (s *RepositoriesService) DisableAutomatedSecurityFixes(ctx context.Context, owner, repository string) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/automated-security-fixes", owner, repository)
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", mediaTypeRequiredAutomatedSecurityFixesPreview)
return s.client.Do(ctx, req, nil)
}
// 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) {
// GitHub API docs: https://developer.github.com/v3/repos/#list-repository-contributors
func (s *RepositoriesService) ListContributors(ctx context.Context, owner string, repository string, opts *ListContributorsOptions) ([]*Contributor, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/contributors", owner, repository)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -494,7 +661,7 @@ func (s *RepositoriesService) ListContributors(ctx context.Context, owner string
// "Python": 7769
// }
//
// GitHub API docs: https://developer.github.com/v3/repos/#list-languages
// GitHub API docs: https://developer.github.com/v3/repos/#list-repository-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)
@ -513,10 +680,10 @@ func (s *RepositoriesService) ListLanguages(ctx context.Context, owner string, r
// 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) {
// GitHub API docs: https://developer.github.com/v3/repos/#list-repository-teams
func (s *RepositoriesService) ListTeams(ctx context.Context, owner string, repo string, opts *ListOptions) ([]*Team, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/teams", owner, repo)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -526,8 +693,6 @@ func (s *RepositoriesService) ListTeams(ctx context.Context, owner string, repo
return nil, nil, err
}
req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
var teams []*Team
resp, err := s.client.Do(ctx, req, &teams)
if err != nil {
@ -547,10 +712,10 @@ type RepositoryTag struct {
// 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) {
// GitHub API docs: https://developer.github.com/v3/repos/#list-repository-tags
func (s *RepositoriesService) ListTags(ctx context.Context, owner string, repo string, opts *ListOptions) ([]*RepositoryTag, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/tags", owner, repo)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -582,6 +747,9 @@ type Protection struct {
RequiredPullRequestReviews *PullRequestReviewsEnforcement `json:"required_pull_request_reviews"`
EnforceAdmins *AdminEnforcement `json:"enforce_admins"`
Restrictions *BranchRestrictions `json:"restrictions"`
RequireLinearHistory *RequireLinearHistory `json:"required_linear_history"`
AllowForcePushes *AllowForcePushes `json:"allow_force_pushes"`
AllowDeletions *AllowDeletions `json:"allow_deletions"`
}
// ProtectionRequest represents a request to create/edit a branch's protection.
@ -590,6 +758,12 @@ type ProtectionRequest struct {
RequiredPullRequestReviews *PullRequestReviewsEnforcementRequest `json:"required_pull_request_reviews"`
EnforceAdmins bool `json:"enforce_admins"`
Restrictions *BranchRestrictionsRequest `json:"restrictions"`
// Enforces a linear commit Git history, which prevents anyone from pushing merge commits to a branch.
RequireLinearHistory *bool `json:"required_linear_history,omitempty"`
// Permits force pushes to the protected branch by anyone with write access to the repository.
AllowForcePushes *bool `json:"allow_force_pushes,omitempty"`
// Allows deletion of the protected branch by anyone with write access to the repository.
AllowDeletions *bool `json:"allow_deletions,omitempty"`
}
// RequiredStatusChecks represents the protection status of a individual branch.
@ -610,7 +784,7 @@ type RequiredStatusChecksRequest struct {
// 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"`
DismissalRestrictions *DismissalRestrictions `json:"dismissal_restrictions,omitempty"`
// 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.
@ -652,6 +826,21 @@ type PullRequestReviewsEnforcementUpdate struct {
RequiredApprovingReviewCount int `json:"required_approving_review_count"`
}
// RequireLinearHistory represents the configuration to enfore branches with no merge commit.
type RequireLinearHistory struct {
Enabled bool `json:"enabled"`
}
// AllowDeletions represents the configuration to accept deletion of protected branches.
type AllowDeletions struct {
Enabled bool `json:"enabled"`
}
// AllowForcePushes represents the configuration to accept forced pushes on protected branches.
type AllowForcePushes struct {
Enabled bool `json:"enabled"`
}
// AdminEnforcement represents the configuration to enforce required status checks for repository administrators.
type AdminEnforcement struct {
URL *string `json:"url,omitempty"`
@ -665,6 +854,8 @@ type BranchRestrictions struct {
Users []*User `json:"users"`
// The list of team slugs with push access.
Teams []*Team `json:"teams"`
// The list of app slugs with push access.
Apps []*App `json:"apps"`
}
// BranchRestrictionsRequest represents the request to create/edit the
@ -676,6 +867,8 @@ type BranchRestrictionsRequest struct {
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"`
// The list of app slugs with push access.
Apps []string `json:"apps,omitempty"`
}
// DismissalRestrictions specifies which users and teams can dismiss pull request reviews.
@ -707,10 +900,10 @@ type SignaturesProtectedBranch struct {
// 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) {
// GitHub API docs: https://developer.github.com/v3/repos/branches/#list-branches
func (s *RepositoriesService) ListBranches(ctx context.Context, owner string, repo string, opts *BranchListOptions) ([]*Branch, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/branches", owner, repo)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -734,7 +927,7 @@ func (s *RepositoriesService) ListBranches(ctx context.Context, owner string, re
// GetBranch gets the specified branch for a repository.
//
// GitHub API docs: https://developer.github.com/v3/repos/#get-branch
// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-a-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)
@ -778,7 +971,7 @@ func (s *RepositoriesService) GetBranchProtection(ctx context.Context, owner, re
// 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
// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-status-checks-protection
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)
@ -800,7 +993,7 @@ func (s *RepositoriesService) GetRequiredStatusChecks(ctx context.Context, owner
// 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
// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-all-status-check-contexts
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)
@ -843,7 +1036,7 @@ func (s *RepositoriesService) UpdateBranchProtection(ctx context.Context, owner,
// RemoveBranchProtection removes the protection of a given branch.
//
// GitHub API docs: https://developer.github.com/v3/repos/branches/#remove-branch-protection
// GitHub API docs: https://developer.github.com/v3/repos/branches/#delete-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)
@ -859,7 +1052,7 @@ func (s *RepositoriesService) RemoveBranchProtection(ctx context.Context, owner,
// GetSignaturesProtectedBranch gets required signatures of protected branch.
//
// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-required-signatures-of-protected-branch
// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-commit-signature-protection
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)
@ -882,7 +1075,7 @@ func (s *RepositoriesService) GetSignaturesProtectedBranch(ctx context.Context,
// 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
// GitHub API docs: https://developer.github.com/v3/repos/branches/#create-commit-signature-protection
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)
@ -904,7 +1097,7 @@ func (s *RepositoriesService) RequireSignaturesOnProtectedBranch(ctx context.Con
// 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
// GitHub API docs: https://developer.github.com/v3/repos/branches/#delete-commit-signature-protection
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)
@ -920,7 +1113,7 @@ func (s *RepositoriesService) OptionalSignaturesOnProtectedBranch(ctx context.Co
// 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
// GitHub API docs: https://developer.github.com/v3/repos/branches/#update-status-check-potection
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)
@ -939,7 +1132,7 @@ func (s *RepositoriesService) UpdateRequiredStatusChecks(ctx context.Context, ow
// 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
// GitHub API docs: https://developer.github.com/v3/licenses/#get-the-license-for-a-repository
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)
@ -958,7 +1151,7 @@ func (s *RepositoriesService) License(ctx context.Context, owner, repo string) (
// 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
// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-pull-request-review-protection
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)
@ -981,7 +1174,7 @@ func (s *RepositoriesService) GetPullRequestReviewEnforcement(ctx context.Contex
// 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
// GitHub API docs: https://developer.github.com/v3/repos/branches/#update-pull-request-review-protection
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)
@ -1004,13 +1197,13 @@ func (s *RepositoriesService) UpdatePullRequestReviewEnforcement(ctx context.Con
// 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
// GitHub API docs: https://developer.github.com/v3/repos/branches/#update-pull-request-review-protection
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{}{}}
data := new(struct {
DismissalRestrictionsRequest `json:"dismissal_restrictions"`
})
req, err := s.client.NewRequest("PATCH", u, data)
if err != nil {
@ -1031,7 +1224,7 @@ func (s *RepositoriesService) DisableDismissalRestrictions(ctx context.Context,
// 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
// GitHub API docs: https://developer.github.com/v3/repos/branches/#delete-pull-request-review-protection
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)
@ -1047,7 +1240,7 @@ func (s *RepositoriesService) RemovePullRequestReviewEnforcement(ctx context.Con
// 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
// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-admin-branch-protection
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)
@ -1070,7 +1263,7 @@ func (s *RepositoriesService) GetAdminEnforcement(ctx context.Context, owner, re
// 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
// GitHub API docs: https://developer.github.com/v3/repos/branches/#set-admin-branch-protection
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)
@ -1092,7 +1285,7 @@ func (s *RepositoriesService) AddAdminEnforcement(ctx context.Context, owner, re
// RemoveAdminEnforcement removes admin enforcement from a protected branch.
//
// GitHub API docs: https://developer.github.com/v3/repos/branches/#remove-admin-enforcement-of-protected-branch
// GitHub API docs: https://developer.github.com/v3/repos/branches/#delete-admin-branch-protection
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)
@ -1113,7 +1306,7 @@ type repositoryTopics struct {
// ListAllTopics lists topics for a repository.
//
// GitHub API docs: https://developer.github.com/v3/repos/#list-all-topics-for-a-repository
// GitHub API docs: https://developer.github.com/v3/repos/#get-all-repository-topics
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)
@ -1135,7 +1328,7 @@ func (s *RepositoriesService) ListAllTopics(ctx context.Context, owner, repo str
// ReplaceAllTopics replaces topics for a repository.
//
// GitHub API docs: https://developer.github.com/v3/repos/#replace-all-topics-for-a-repository
// GitHub API docs: https://developer.github.com/v3/repos/#replace-all-repository-topics
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{
@ -1161,6 +1354,93 @@ func (s *RepositoriesService) ReplaceAllTopics(ctx context.Context, owner, repo
return t.Names, resp, nil
}
// ListApps lists the Github apps that have push access to a given protected branch.
// It requires the Github apps to have `write` access to the `content` permission.
//
// GitHub API docs: https://developer.github.com/v3/repos/branches/#list-apps-with-access-to-the-protected-branch
func (s *RepositoriesService) ListApps(ctx context.Context, owner, repo, branch string) ([]*App, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
var apps []*App
resp, err := s.client.Do(ctx, req, &apps)
if err != nil {
return nil, resp, err
}
return apps, resp, nil
}
// ReplaceAppRestrictions replaces the apps that have push access to a given protected branch.
// It removes all apps that previously had push access and grants push access to the new list of apps.
// It requires the Github apps to have `write` access to the `content` permission.
//
// Note: The list of users, apps, and teams in total is limited to 100 items.
//
// GitHub API docs: https://developer.github.com/v3/repos/branches/#set-app-access-restrictions
func (s *RepositoriesService) ReplaceAppRestrictions(ctx context.Context, owner, repo, branch string, slug []string) ([]*App, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch)
req, err := s.client.NewRequest("PUT", u, slug)
if err != nil {
return nil, nil, err
}
var apps []*App
resp, err := s.client.Do(ctx, req, &apps)
if err != nil {
return nil, nil, err
}
return apps, resp, nil
}
// AddAppRestrictions grants the specified apps push access to a given protected branch.
// It requires the Github apps to have `write` access to the `content` permission.
//
// Note: The list of users, apps, and teams in total is limited to 100 items.
//
// GitHub API docs: https://developer.github.com/v3/repos/branches/#add-app-access-restrictions
func (s *RepositoriesService) AddAppRestrictions(ctx context.Context, owner, repo, branch string, slug []string) ([]*App, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch)
req, err := s.client.NewRequest("POST", u, slug)
if err != nil {
return nil, nil, err
}
var apps []*App
resp, err := s.client.Do(ctx, req, &apps)
if err != nil {
return nil, nil, err
}
return apps, resp, nil
}
// RemoveAppRestrictions removes the ability of an app to push to this branch.
// It requires the Github apps to have `write` access to the `content` permission.
//
// Note: The list of users, apps, and teams in total is limited to 100 items.
//
// GitHub API docs: https://developer.github.com/v3/repos/branches/#remove-app-access-restrictions
func (s *RepositoriesService) RemoveAppRestrictions(ctx context.Context, owner, repo, branch string, slug []string) ([]*App, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch)
req, err := s.client.NewRequest("DELETE", u, slug)
if err != nil {
return nil, nil, err
}
var apps []*App
resp, err := s.client.Do(ctx, req, &apps)
if err != nil {
return nil, nil, err
}
return apps, resp, nil
}
// TransferRequest represents a request to transfer a repository.
type TransferRequest struct {
NewOwner string `json:"new_owner"`
@ -1184,8 +1464,34 @@ func (s *RepositoriesService) Transfer(ctx context.Context, owner, repo string,
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
}
// DispatchRequestOptions represents a request to trigger a repository_dispatch event.
type DispatchRequestOptions struct {
// EventType is a custom webhook event name. (Required.)
EventType string `json:"event_type"`
// ClientPayload is a custom JSON payload with extra information about the webhook event.
// Defaults to an empty JSON object.
ClientPayload *json.RawMessage `json:"client_payload,omitempty"`
}
// Dispatch triggers a repository_dispatch event in a GitHub Actions workflow.
//
// GitHub API docs: https://developer.github.com/v3/repos/#create-a-repository-dispatch-event
func (s *RepositoriesService) Dispatch(ctx context.Context, owner, repo string, opts DispatchRequestOptions) (*Repository, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/dispatches", owner, repo)
req, err := s.client.NewRequest("POST", u, &opts)
if err != nil {
return nil, nil, err
}
r := new(Repository)
resp, err := s.client.Do(ctx, req, r)

View File

@ -26,12 +26,25 @@ type ListCollaboratorsOptions struct {
ListOptions
}
// CollaboratorInvitation represents an invitation created when adding a collaborator.
// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#response-when-a-new-invitation-is-created
type CollaboratorInvitation struct {
ID *int64 `json:"id,omitempty"`
Repo *Repository `json:"repository,omitempty"`
Invitee *User `json:"invitee,omitempty"`
Inviter *User `json:"inviter,omitempty"`
Permissions *string `json:"permissions,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
URL *string `json:"url,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
}
// 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) {
// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#list-repository-collaborators
func (s *RepositoriesService) ListCollaborators(ctx context.Context, owner, repo string, opts *ListCollaboratorsOptions) ([]*User, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/collaborators", owner, repo)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -41,8 +54,6 @@ func (s *RepositoriesService) ListCollaborators(ctx context.Context, owner, repo
return nil, nil, err
}
req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
var users []*User
resp, err := s.client.Do(ctx, req, &users)
if err != nil {
@ -57,7 +68,7 @@ func (s *RepositoriesService) ListCollaborators(ctx context.Context, owner, 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
// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#check-if-a-user-is-a-repository-collaborator
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)
@ -80,7 +91,7 @@ type RepositoryPermissionLevel struct {
}
// 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
// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#get-repository-permissions-for-a-user
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)
@ -104,6 +115,8 @@ type RepositoryAddCollaboratorOptions struct {
// 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
// maintain - team members can manage the repository without access to sensitive or destructive actions.
// triage - team members can proactively manage issues and pull requests without write access.
//
// Default value is "push". This option is only valid for organization-owned repositories.
Permission string `json:"permission,omitempty"`
@ -112,21 +125,25 @@ type RepositoryAddCollaboratorOptions struct {
// 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) {
// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#add-a-repository-collaborator
func (s *RepositoriesService) AddCollaborator(ctx context.Context, owner, repo, user string, opts *RepositoryAddCollaboratorOptions) (*CollaboratorInvitation, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user)
req, err := s.client.NewRequest("PUT", u, opt)
req, err := s.client.NewRequest("PUT", u, opts)
if err != nil {
return nil, err
return nil, nil, err
}
return s.client.Do(ctx, req, nil)
acr := new(CollaboratorInvitation)
resp, err := s.client.Do(ctx, req, acr)
if err != nil {
return nil, resp, err
}
return acr, resp, 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
// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#remove-a-repository-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)

View File

@ -16,6 +16,7 @@ type RepositoryComment struct {
HTMLURL *string `json:"html_url,omitempty"`
URL *string `json:"url,omitempty"`
ID *int64 `json:"id,omitempty"`
NodeID *string `json:"node_id,omitempty"`
CommitID *string `json:"commit_id,omitempty"`
User *User `json:"user,omitempty"`
Reactions *Reactions `json:"reactions,omitempty"`
@ -36,9 +37,9 @@ func (r RepositoryComment) String() string {
// 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) {
func (s *RepositoriesService) ListComments(ctx context.Context, owner, repo string, opts *ListOptions) ([]*RepositoryComment, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/comments", owner, repo)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -62,10 +63,10 @@ func (s *RepositoriesService) ListComments(ctx context.Context, owner, repo stri
// 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) {
// GitHub API docs: https://developer.github.com/v3/repos/comments/#list-commit-comments
func (s *RepositoriesService) ListCommitComments(ctx context.Context, owner, repo, sha string, opts *ListOptions) ([]*RepositoryComment, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/commits/%v/comments", owner, repo, sha)
u, err := addOptions(u, opt)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
@ -109,7 +110,7 @@ func (s *RepositoriesService) CreateComment(ctx context.Context, owner, repo, sh
// GetComment gets a single comment from a repository.
//
// GitHub API docs: https://developer.github.com/v3/repos/comments/#get-a-single-commit-comment
// GitHub API docs: https://developer.github.com/v3/repos/comments/#get-a-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)

Some files were not shown because too many files have changed in this diff Show More