O Go-Github é uma biblioteca de clientes GO para acessar a API Github V3.
O Go-Github requer Go versão 1.17 e maior e a biblioteca é testada contra a versão go 1.22 e maior. A Política de Suporte da Versão do Go-Github Tracks Go. Fazemos o possível para não quebrar as versões mais antigas do GO, se não precisarmos, mas, devido a restrições de ferramentas, nem sempre testamos versões mais antigas.
Se você estiver interessado em usar a API V4 do GraphQL, a biblioteca recomendada é Shurcool/Githubv4.
O Go-Github é compatível com os lançamentos do Modern Go no modo de módulo, com o Go Installed:
go get github.com/google/go-github/v68Resolverá e adicionará o pacote ao módulo de desenvolvimento atual, juntamente com suas dependências.
Como alternativa, o mesmo pode ser alcançado se você usar a importação em um pacote:
import "github.com/google/go-github/v68/github" e correr, go get sem parâmetros.
Finalmente, para usar a versão do topo do tronco deste repositório, use o seguinte comando:
go get github.com/google/go-github/v68@master import "github.com/google/go-github/v68/github" // with go modules enabled (GO111MODULE=on or outside GOPATH)
import "github.com/google/go-github/github" // with go modules disabledConstrua um novo cliente do GitHub e use os vários serviços do cliente para acessar diferentes partes da API do GitHub. Por exemplo:
client := github . NewClient ( nil )
// list all organizations for user "willnorris"
orgs , _ , err := client . Organizations . List ( context . Background (), "willnorris" , nil )Alguns métodos de API têm parâmetros opcionais que podem ser passados. Por exemplo:
client := github . NewClient ( nil )
// list public repositories for org "github"
opt := & github. RepositoryListByOrgOptions { Type : "public" }
repos , _ , err := client . Repositories . ListByOrg ( context . Background (), "github" , opt )Os serviços de um cliente dividem a API em pedaços lógicos e correspondem à estrutura da documentação da API do GitHub.
Nota: Usando o pacote de contexto, pode -se facilmente passar sinais de cancelamento e prazos para vários serviços do cliente para lidar com uma solicitação. Caso não haja contexto disponível, context.Background() pode ser usado como ponto de partida.
Para mais trechos de código de amostra, acesse o diretório de exemplo.
Use o método WithAuthToken para configurar seu cliente para autenticar usando um token OAuth (por exemplo, um token de acesso pessoal). É isso que é necessário para a maioria dos casos de uso, além dos aplicativos do GitHub.
client := github . NewClient ( nil ). WithAuthToken ( "... your access token ..." )Observe que, ao usar um cliente autenticado, todas as chamadas feitas pelo cliente incluirão o token OAuth especificado. Portanto, clientes autenticados quase nunca devem ser compartilhados entre diferentes usuários.
Para métodos de API que requerem autenticação básica HTTP, use o BasicAuthTransport .
A autenticação de aplicativos do Github pode ser fornecida por diferentes PKGs como Bradleyfalzon/Ghinstallation ou Jferrl/Go-Githubauth.
NOTA : A maioria dos pontos de extremidade (Ex.
GET /rate_limit) requer autenticação de token de acesso, enquanto alguns outros (Ex.GET /app/hook/deliveries) exigem autenticação JWT.
ghinstallation fornece Transport , que implementa http.RoundTripper para fornecer autenticação como uma instalação para aplicativos do GitHub.
Aqui está um exemplo de como autenticar como um aplicativo Github usando o pacote ghinstallation :
import (
"net/http"
"github.com/bradleyfalzon/ghinstallation/v2"
"github.com/google/go-github/v68/github"
)
func main () {
// Wrap the shared transport for use with the integration ID 1 authenticating with installation ID 99.
itr , err := ghinstallation . NewKeyFromFile ( http . DefaultTransport , 1 , 99 , "2016-10-19.private-key.pem" )
// Or for endpoints that require JWT authentication
// itr, err := ghinstallation.NewAppsTransportKeyFromFile(http.DefaultTransport, 1, "2016-10-19.private-key.pem")
if err != nil {
// Handle error.
}
// Use installation transport with client.
client := github . NewClient ( & http. Client { Transport : itr })
// Use client...
} go-githubauth implementa um conjunto de oauth2.TokenSource a ser usado com oauth2.Client . Um oauth2.Client pode ser injetado no github.Client para autenticar solicitações.
Outro exemplo usando go-githubauth :
package main
import (
"context"
"fmt"
"os"
"strconv"
"github.com/google/go-github/v68/github"
"github.com/jferrl/go-githubauth"
"golang.org/x/oauth2"
)
func main () {
privateKey := [] byte ( os . Getenv ( "GITHUB_APP_PRIVATE_KEY" ))
appTokenSource , err := githubauth . NewApplicationTokenSource ( 1112 , privateKey )
if err != nil {
fmt . Println ( "Error creating application token source:" , err )
return
}
installationTokenSource := githubauth . NewInstallationTokenSource ( 1113 , appTokenSource )
// oauth2.NewClient uses oauth2.ReuseTokenSource to reuse the token until it expires.
// The token will be automatically refreshed when it expires.
// InstallationTokenSource has the mechanism to refresh the token when it expires.
httpClient := oauth2 . NewClient ( context . Background (), installationTokenSource )
client := github . NewClient ( httpClient )
}Nota : Para interagir com certas APIs, por exemplo, escrevendo um arquivo em um repositório, é preciso gerar um token de instalação usando o ID de instalação do aplicativo GitHub e autenticar com o método OAuth mencionado acima. Veja os exemplos.
O GitHub impõe um limite de taxa a todos os clientes da API. Clientes não autenticados são limitados a 60 solicitações por hora, enquanto clientes autenticados podem fazer até 5.000 solicitações por hora. A API de pesquisa tem um limite de taxa personalizado. Clientes não autenticados são limitados a 10 solicitações por minuto, enquanto clientes autenticados podem fazer até 30 solicitações por minuto. Para receber o limite de taxa mais alta ao fazer chamadas que não são emitidas em nome de um usuário, use UnauthenticatedRateLimitedTransport .
O valor Response.Rate retornada contém as informações limitadas da taxa da chamada mais recente da API. Se uma resposta recente o suficiente não estiver disponível, você pode usar RateLimits para buscar os dados limitados da taxa mais atualizada para o cliente.
Para detectar um erro de limite de taxa de API, você pode verificar se seu tipo é *github.RateLimitError :
repos , _ , err := client . Repositories . List ( ctx , "" , nil )
if _ , ok := err .( * github. RateLimitError ); ok {
log . Println ( "hit rate limit" )
}Saiba mais sobre a limitação da taxa de github em "pontos de extremidade da API REST para limites de taxa".
Além desses limites de taxa, o GitHub impõe um limite de taxa secundária a todos os clientes da API. Esse limite de taxa impede que os clientes façam muitas solicitações simultâneas.
Para detectar um erro de limite de taxa secundária da API, você pode verificar se o tipo é *github.AbuseRateLimitError :
repos , _ , err := client . Repositories . List ( ctx , "" , nil )
if _ , ok := err .( * github. AbuseRateLimitError ); ok {
log . Println ( "hit secondary rate limit" )
} Como alternativa, você pode bloquear até que o limite da taxa seja redefinido usando o context.WithValue .
repos , _ , err := client . Repositories . List ( context . WithValue ( ctx , github . SleepUntilPrimaryRateLimitResetWhenRateLimited , true ), "" , nil )Você pode usar o Gofri/Go-Github-Ratelimit para lidar com a taxa secundária limite o sono e a correção para você.
Saiba mais sobre a taxa secundária do Github limitando "sobre limites de taxa secundária".
Alguns terminais podem retornar um código de status aceito 202, o que significa que as informações necessárias ainda não estão prontas e estavam programadas para serem reunidas no lado do GitHub. Métodos conhecidos por se comportar como esse estão documentados especificando esse comportamento.
Para detectar essa condição de erro, você pode verificar se seu tipo é *github.AcceptedError :
stats , _ , err := client . Repositories . ListContributorsStats ( ctx , org , repo )
if _ , ok := err .( * github. AcceptedError ); ok {
log . Println ( "scheduled on GitHub side" )
} A API do GitHub tem um bom suporte para solicitações condicionais, o que ajudará a impedir que você queira o limite da taxa, além de ajudar a acelerar seu aplicativo. go-github não lida diretamente com solicitações condicionais, mas é projetado para trabalhar com um http.Transport em cache. Recomendamos o uso de Gregjones/httpcache para isso. Por exemplo:
import "github.com/gregjones/httpcache"
client := github . NewClient (
httpcache . NewMemoryCacheTransport (). Client ()
). WithAuthToken ( os . Getenv ( "GITHUB_TOKEN" ))Saiba mais sobre as solicitações condicionais do GitHub em "Use solicitações condicionais, se apropriado".
Todas as estruturas para recursos do github usam valores de ponteiro para todos os campos não repetidos. Isso permite distinguir entre os campos Unset e os definidos como um valor zero. As funções auxiliares foram fornecidas para criar facilmente esses ponteiros para valores de string, bool e int. Por exemplo:
// create a new private repository named "foo"
repo := & github. Repository {
Name : github . Ptr ( "foo" ),
Private : github . Ptr ( true ),
}
client . Repositories . Create ( ctx , "" , repo )Os usuários que trabalharam com buffers de protocolo devem achar esse padrão familiar.
Todos os pedidos de coleções de recursos (repositórios, solicitações de puxar, problemas etc.) apóiam a paginação. As opções de paginação são descritas na estrutura github.ListOptions e passadas para os métodos da lista diretamente ou como um tipo incorporado de uma estrutura de opções de lista mais específica (por exemplo, github.PullRequestListOptions ). As informações das páginas estão disponíveis através da estrutura github.Response .
client := github . NewClient ( nil )
opt := & github. RepositoryListByOrgOptions {
ListOptions : github. ListOptions { PerPage : 10 },
}
// get all pages of results
var allRepos [] * github. Repository
for {
repos , resp , err := client . Repositories . ListByOrg ( ctx , "github" , opt )
if err != nil {
return err
}
allRepos = append ( allRepos , repos ... )
if resp . NextPage == 0 {
break
}
opt . Page = resp . NextPage
} GO V1.23 apresenta o novo pacote iter .
Com o pacote enrichman/gh-iter , é possível criar iteradores para go-github . O iterador lidará com a paginação para você, percorrendo todos os resultados disponíveis.
client := github . NewClient ( nil )
var allRepos [] * github. Repository
// create an iterator and start looping through all the results
repos := ghiter . NewFromFn1 ( client . Repositories . ListByOrg , "github" )
for repo := range repos . All () {
allRepos = append ( allRepos , repo )
} Para uso completo do enrichman/gh-iter , consulte os documentos de pacote completo.
go-github fornece estruturas para quase todos os eventos do Github Webhook, bem como funções para validá-las e cargas úteis JSON solteiras de http.Request structs.
func ( s * GitHubEventMonitor ) ServeHTTP ( w http. ResponseWriter , r * http. Request ) {
payload , err := github . ValidatePayload ( r , s . webhookSecretKey )
if err != nil { ... }
event , err := github . ParseWebHook ( github . WebHookType ( r ), payload )
if err != nil { ... }
switch event := event .( type ) {
case * github. CommitCommentEvent :
processCommitCommentEvent ( event )
case * github. CreateEvent :
processCreateEvent ( event )
...
}
}Além disso, existem bibliotecas como CBRGM/Githubevents que se baseiam no exemplo acima e fornecem funções para assinar retornos de chamada para eventos específicos.
Para uso completo do Go-Github, consulte os documentos completos do pacote.
go-githubO repo Migueleliasweb/Go-Github-Mock fornece uma maneira de zombar de respostas. Verifique o repositório para obter mais detalhes.
Você pode executar testes de integração no diretório test . Veja os testes de integração Readme.
Eu gostaria de cobrir toda a API do GitHub e as contribuições são sempre bem -vindas. O padrão de chamada está muito bem estabelecido; portanto, adicionar novos métodos é relativamente direto. Consulte CONTRIBUTING.md para obter detalhes.
Em geral, o Go-Github segue o Semver o mais próximo possível, para marcar lançamentos do pacote. Para bibliotecas independentes, a aplicação do versão semântica é relativamente direta e geralmente compreendida. Mas como o Go-Github é uma biblioteca de clientes para a API do GitHub, que muda o comportamento e, como normalmente somos bastante agressivos ao implementar os recursos de visualização da API do GitHub, adotamos a seguinte política de versão:
A funcionalidade de visualização pode assumir a forma de métodos inteiros ou simplesmente dados adicionais retornados de um método que não é de previsão. Consulte a documentação da API do GitHub para obter detalhes sobre a funcionalidade de visualização.
A partir de 2022-11-28, o Github anunciou que está começando a vers sua API V3 com base em "Calendar-Versioning".
Na prática, nosso objetivo é fazer com que a versão por método substitua (pelo menos na biblioteca central) rara e temporária.
Nossa compreensão dos documentos do Github é que eles estarão acelerando toda a API para cada nova versão baseada em data, mesmo que apenas alguns métodos tenham mudanças de quebra. Outros métodos aceitarão a nova versão com sua funcionalidade existente. Então, quando uma nova versão baseada em data da API do GitHub é lançada, nós (os mantenedores de repo) planejamos:
Atualize cada método que teve mudanças de quebra, substituindo o cabeçalho da versão da API por método. Isso pode acontecer em um ou vários compromissos e prs, e tudo é feito no ramo principal.
Depois que todos os métodos com mudanças de ruptura forem atualizados, tenha uma confirmação final que supere a versão da API padrão e remova todas as substituições por método. Isso agora receberia uma versão importante quando o próximo lançamento do Go-Github for feito.
A tabela a seguir identifica qual versão da API do GitHub é suportada por essas versões (e passadas) deste repo (Go-Github). As versões anteriores a 48.2.0 não estão listadas.
| versão go-github | Versão da API do Github V3 |
|---|---|
| 68.0.0 | 2022-11-28 |
| ... | 2022-11-28 |
| 48.2.0 | 2022-11-28 |
Esta biblioteca é distribuída sob a licença de estilo BSD encontrada no arquivo de licença.