Go-Github adalah perpustakaan klien GO untuk mengakses Github API V3.
Go-Github membutuhkan GO versi 1.17 dan lebih besar dan perpustakaan diuji terhadap GO versi 1.22 dan lebih besar. Kebijakan Dukungan Versi Go-Github Tracks Go. Kami melakukan yang terbaik untuk tidak memecahkan versi GO yang lebih lama jika kami tidak harus melakukannya, tetapi karena kendala perkakas, kami tidak selalu menguji versi yang lebih lama.
Jika Anda tertarik menggunakan GraphQL API V4, pustaka yang disarankan adalah Shurcool/Githubv4.
Go-Github kompatibel dengan rilis GO modern dalam mode modul, dengan GO diinstal:
go get github.com/google/go-github/v68akan menyelesaikan dan menambahkan paket ke modul pengembangan saat ini, bersama dengan ketergantungannya.
Atau hal yang sama dapat dicapai jika Anda menggunakan impor dalam suatu paket:
import "github.com/google/go-github/v68/github" dan jalankan go get tanpa parameter.
Akhirnya, untuk menggunakan versi top-of-trunk dari repo ini, gunakan perintah berikut:
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 disabledBangun klien GitHub baru, lalu gunakan berbagai layanan pada klien untuk mengakses bagian -bagian API GitHub yang berbeda. Misalnya:
client := github . NewClient ( nil )
// list all organizations for user "willnorris"
orgs , _ , err := client . Organizations . List ( context . Background (), "willnorris" , nil )Beberapa metode API memiliki parameter opsional yang dapat dilewati. Misalnya:
client := github . NewClient ( nil )
// list public repositories for org "github"
opt := & github. RepositoryListByOrgOptions { Type : "public" }
repos , _ , err := client . Repositories . ListByOrg ( context . Background (), "github" , opt )Layanan klien membagi API menjadi potongan logis dan sesuai dengan struktur dokumentasi API GitHub.
Catatan: Menggunakan paket konteks, seseorang dapat dengan mudah memberikan sinyal pembatalan dan tenggat waktu ke berbagai layanan klien untuk menangani permintaan. Jika tidak ada konteks yang tersedia, maka context.Background() dapat digunakan sebagai titik awal.
Untuk lebih banyak cuplikan kode sampel, pergilah ke direktori contoh.
Gunakan metode WithAuthToken untuk mengonfigurasi klien Anda untuk mengotentikasi menggunakan token OAuth (misalnya, token akses pribadi). Inilah yang dibutuhkan untuk sebagian besar kasus penggunaan selain dari aplikasi GitHub.
client := github . NewClient ( nil ). WithAuthToken ( "... your access token ..." )Perhatikan bahwa saat menggunakan klien yang diautentikasi, semua panggilan yang dilakukan oleh klien akan menyertakan token OAuth yang ditentukan. Oleh karena itu, klien yang diautentikasi hampir tidak pernah dibagikan di antara pengguna yang berbeda.
Untuk metode API yang memerlukan otentikasi dasar HTTP, gunakan BasicAuthTransport .
Otentikasi Aplikasi GitHub dapat disediakan oleh PKG yang berbeda seperti Bradleyfalzon/Ghinstallation atau JFerrl/Go-GithubAuth.
Catatan : Sebagian besar titik akhir (Kel.
GET /rate_limit) memerlukan otentikasi token akses sementara beberapa lainnya (mis.GET /app/hook/deliveries) memerlukan otentikasi JWT.
ghinstallation menyediakan Transport , yang mengimplementasikan http.RoundTripper untuk memberikan otentikasi sebagai instalasi untuk aplikasi github.
Berikut adalah contoh cara mengotentikasi sebagai aplikasi github menggunakan paket 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 mengimplementasikan satu set oauth2.TokenSource untuk digunakan dengan oauth2.Client . oauth2.Client dapat disuntikkan ke dalam github.Client untuk mengotentikasi permintaan.
Contoh lain menggunakan 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 )
}Catatan : Untuk berinteraksi dengan API tertentu, misalnya menulis file ke repo, seseorang harus menghasilkan token instalasi menggunakan ID instalasi aplikasi GitHub dan mengotentikasi dengan metode oAuth yang disebutkan di atas. Lihat contohnya.
GitHub memaksakan batas tarif pada semua klien API. Klien yang tidak aautentikasi dibatasi hingga 60 permintaan per jam, sementara klien yang diautentikasi dapat membuat hingga 5.000 permintaan per jam. API pencarian memiliki batas tarif khusus. Klien yang tidak aautentikasi dibatasi hingga 10 permintaan per menit, sementara klien yang diautentikasi dapat membuat hingga 30 permintaan per menit. Untuk menerima batas tarif yang lebih tinggi saat melakukan panggilan yang tidak dikeluarkan atas nama pengguna, gunakan UnauthenticatedRateLimitedTransport .
Nilai Response.Rate yang dikembalikan. Nilai later berisi informasi batas tingkat dari panggilan API terbaru. Jika respons yang cukup baru tidak tersedia, Anda dapat menggunakan RateLimits untuk mengambil data batas tingkat terkini untuk klien.
Untuk mendeteksi kesalahan batas laju API, Anda dapat memeriksa apakah jenisnya *github.RateLimitError :
repos , _ , err := client . Repositories . List ( ctx , "" , nil )
if _ , ok := err .( * github. RateLimitError ); ok {
log . Println ( "hit rate limit" )
}Pelajari lebih lanjut tentang pembatasan laju gitub di "titik akhir API REST untuk batas tingkat".
Selain batas tingkat ini, GitHub memaksakan batas tarif sekunder pada semua klien API. Batas tarif ini mencegah klien dari membuat terlalu banyak permintaan bersamaan.
Untuk mendeteksi kesalahan batas tingkat sekunder API, Anda dapat memeriksa apakah jenisnya *github.AbuseRateLimitError :
repos , _ , err := client . Repositories . List ( ctx , "" , nil )
if _ , ok := err .( * github. AbuseRateLimitError ); ok {
log . Println ( "hit secondary rate limit" )
} Atau, Anda dapat memblokir sampai batas laju diatur ulang dengan menggunakan context.WithValue Metode Nilai:
repos , _ , err := client . Repositories . List ( context . WithValue ( ctx , github . SleepUntilPrimaryRateLimitResetWhenRateLimited , true ), "" , nil )Anda dapat menggunakan gofri/go-github-ratelimit untuk menangani batas laju sekunder tidur dan retry untuk Anda.
Pelajari lebih lanjut tentang pembatasan tingkat sekunder GitHub dalam "tentang batas tingkat sekunder".
Beberapa titik akhir dapat mengembalikan kode status 202 yang diterima, yang berarti bahwa informasi yang diperlukan belum siap dan dijadwalkan akan dikumpulkan di sisi GitHub. Metode yang diketahui berperilaku seperti ini didokumentasikan menentukan perilaku ini.
Untuk mendeteksi kondisi kesalahan ini, Anda dapat memeriksa apakah jenisnya *github.AcceptedError :
stats , _ , err := client . Repositories . ListContributorsStats ( ctx , org , repo )
if _ , ok := err .( * github. AcceptedError ); ok {
log . Println ( "scheduled on GitHub side" )
} API GitHub memiliki dukungan yang baik untuk permintaan bersyarat yang akan membantu mencegah Anda terbakar melalui batas tarif Anda, serta membantu mempercepat aplikasi Anda. go-github tidak menangani permintaan bersyarat secara langsung, tetapi sebaliknya dirancang untuk bekerja dengan caching http.Transport . Kami merekomendasikan menggunakan Gregjones/httpcache untuk itu. Misalnya:
import "github.com/gregjones/httpcache"
client := github . NewClient (
httpcache . NewMemoryCacheTransport (). Client ()
). WithAuthToken ( os . Getenv ( "GITHUB_TOKEN" ))Pelajari lebih lanjut tentang permintaan bersyarat GitHub dalam "Gunakan permintaan bersyarat jika sesuai".
Semua struct untuk sumber daya GitHub menggunakan nilai pointer untuk semua bidang yang tidak diulang. Ini memungkinkan membedakan antara bidang yang tidak disetel dan yang diatur ke nilai nol. Fungsi helper telah disediakan untuk dengan mudah membuat pointer ini untuk nilai string, bool, dan int. Misalnya:
// create a new private repository named "foo"
repo := & github. Repository {
Name : github . Ptr ( "foo" ),
Private : github . Ptr ( true ),
}
client . Repositories . Create ( ctx , "" , repo )Pengguna yang telah bekerja dengan buffer protokol harus menemukan pola ini akrab.
Semua permintaan untuk koleksi sumber daya (repo, permintaan tarik, masalah, dll.) Mendukung pagination. Opsi pagination dijelaskan dalam github.ListOptions struct dan diteruskan ke metode daftar secara langsung atau sebagai jenis tertanam dari struct opsi daftar yang lebih spesifik (misalnya github.PullRequestListOptions ). Informasi halaman tersedia melalui github.Response struct.
client := github . NewClient ( nil )
opt := & github. RepositoryListByOrgOptions {
ListOptions : github. ListOptions { PerPage : 10 },
}
// get all pages of results
var allRepos [] * github. Repository
for {
repos , resp , err := client . Repositories . ListByOrg ( ctx , "github" , opt )
if err != nil {
return err
}
allRepos = append ( allRepos , repos ... )
if resp . NextPage == 0 {
break
}
opt . Page = resp . NextPage
} GO V1.23 memperkenalkan paket iter baru.
Dengan paket enrichman/gh-iter , dimungkinkan untuk membuat iterator untuk go-github . Iterator akan menangani pagination untuk Anda, melingkarkan semua hasil yang tersedia.
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 )
} Untuk penggunaan lengkap enrichman/gh-iter , lihat dokumen paket lengkap.
go-github menyediakan struct untuk hampir semua acara Webhook Github serta fungsi untuk memvalidasi mereka dan muatan JSON unmarshal dari http.Request struct.
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 )
...
}
}Selain itu, ada perpustakaan seperti CBRGM/Githubevents yang membangun berdasarkan contoh di atas dan menyediakan fungsi untuk berlangganan panggilan balik ke acara tertentu.
Untuk penggunaan lengkap go-github, lihat paket lengkap dokumen.
go-githubRepo MigueleliasWeb/Go-Github-Mock menyediakan cara untuk mengejek tanggapan. Periksa repo untuk lebih jelasnya.
Anda dapat menjalankan tes integrasi dari direktori test . Lihat Tes Integrasi Readme.
Saya ingin membahas seluruh API GitHub dan kontribusi tentu saja selalu diterima. Pola panggilan cukup mapan, jadi menambahkan metode baru relatif mudah. Lihat CONTRIBUTING.md untuk detailnya.
Secara umum, Go-Github mengikuti SEMVER sedekat mungkin untuk penandaan rilis paket. Untuk perpustakaan mandiri, penerapan versi semantik relatif mudah dan umumnya dipahami. Tetapi karena Go-Github adalah perpustakaan klien untuk Github API, yang dengan sendirinya mengubah perilaku, dan karena kami biasanya cukup agresif tentang menerapkan fitur pratinjau API GitHub, kami telah mengadopsi kebijakan versi berikut:
Fungsionalitas pratinjau dapat mengambil bentuk seluruh metode atau hanya data tambahan yang dikembalikan dari metode non-preview. Lihat dokumentasi API GitHub untuk perincian tentang fungsionalitas pratinjau.
Pada 2022-11-28, GitHub telah mengumumkan bahwa mereka mulai versi V3 API mereka berdasarkan "Kalender-Lingkaran".
Dalam praktiknya, tujuan kami adalah untuk membuat versi per metode yang ditimpa (setidaknya di perpustakaan inti) langka dan sementara.
Pemahaman kami tentang dokumen GitHub adalah bahwa mereka akan memutar seluruh API untuk setiap versi berbasis tanggal baru, bahkan jika hanya beberapa metode yang mengalami perubahan. Metode lain akan menerima versi baru dengan fungsionalitas yang ada. Jadi ketika versi GitHub API berbasis kencan baru dirilis, kami (Pemelihara Repo) berencana untuk:
Perbarui setiap metode yang mengalami perubahan, mengesampingkan header versi API per-metode mereka. Ini dapat terjadi dalam satu atau beberapa komitmen dan PR, dan semuanya dilakukan di cabang utama.
Setelah semua metode dengan perubahan memecahkan telah diperbarui, memiliki komit akhir yang menabrak versi API default, dan menghapus semua timpang per-metode. Itu sekarang akan mendapatkan benjolan versi utama saat rilis go-github berikutnya dibuat.
Tabel berikut mengidentifikasi versi API GitHub mana yang didukung oleh versi ini (dan masa lalu) dari repo ini (go-github). Versi sebelum 48.2.0 tidak terdaftar.
| Versi Go-Github | Versi API GitHub V3 |
|---|---|
| 68.0.0 | 2022-11-28 |
| ... | 2022-11-28 |
| 48.2.0 | 2022-11-28 |
Perpustakaan ini didistribusikan di bawah lisensi gaya BSD yang ditemukan dalam file lisensi.