Go library for accessing the GitHub API

go-github

GoDoc Test Status Test Coverage Discuss at go-github@googlegroups.com CII Best Practices

go-github is a Go client library for accessing the GitHub API v3.

Currently, go-github requires Go version 1.9 or greater. go-github tracks Go's version support policy. We do our best not to break older versions of Go if we don't have to, but due to tooling constraints, we don't always test older versions.

If you're interested in using the GraphQL API v4, the recommended library is shurcooL/githubv4.

Usage

import "github.com/google/go-github/v33/github"	// with go modules enabled (GO111MODULE=on or outside GOPATH)
import "github.com/google/go-github/github" // with go modules disabled

Construct a new GitHub client, then use the various services on the client to access different parts of the GitHub API. For example:

client := github.NewClient(nil)

// list all organizations for user "willnorris"
orgs, _, err := client.Organizations.List(context.Background(), "willnorris", nil)

Some API methods have optional parameters that can be passed. For example:

client := github.NewClient(nil)

// list public repositories for org "github"
opt := &github.RepositoryListByOrgOptions{Type: "public"}
repos, _, err := client.Repositories.ListByOrg(context.Background(), "github", opt)

The services of a client divide the API into logical chunks and correspond to the structure of the GitHub API documentation at https://docs.github.com/en/free-pro-team@latest/rest/reference/.

NOTE: Using the context package, one can easily pass cancelation signals and deadlines to various services of the client for handling a request. In case there is no context available, then context.Background() can be used as a starting point.

For more sample code snippets, head over to the example directory.

Authentication

The go-github library does not directly handle authentication. Instead, when creating a new client, pass an http.Client that can handle authentication for you. The easiest and recommended way to do this is using the oauth2 library, but you can always use any other library that provides an http.Client. If you have an OAuth2 access token (for example, a personal API token), you can use it with the oauth2 library using:

import "golang.org/x/oauth2"

func main() {
	ctx := context.Background()
	ts := oauth2.StaticTokenSource(
		&oauth2.Token{AccessToken: "... your access token ..."},
	)
	tc := oauth2.NewClient(ctx, ts)

	client := github.NewClient(tc)

	// list all repositories for the authenticated user
	repos, _, err := client.Repositories.List(ctx, "", nil)
}

Note that when using an authenticated Client, all calls made by the client will include the specified OAuth token. Therefore, authenticated clients should almost never be shared between different users.

See the oauth2 docs for complete instructions on using that library.

For API methods that require HTTP Basic Authentication, use the BasicAuthTransport.

GitHub Apps authentication can be provided by the ghinstallation package.

import "github.com/bradleyfalzon/ghinstallation"

func main() {
	// Wrap the shared transport for use with the integration ID 1 authenticating with installation ID 99.
	itr, err := ghinstallation.NewKeyFromFile(http.DefaultTransport, 1, 99, "2016-10-19.private-key.pem")
	if err != nil {
		// Handle error.
	}

	// Use installation transport with client.
	client := github.NewClient(&http.Client{Transport: itr})

	// Use client...
}

Rate Limiting

GitHub imposes a rate limit on all API clients. Unauthenticated clients are limited to 60 requests per hour, while authenticated clients can make up to 5,000 requests per hour. The Search API has a custom rate limit. Unauthenticated clients are limited to 10 requests per minute, while authenticated clients can make up to 30 requests per minute. To receive the higher rate limit when making calls that are not issued on behalf of a user, use UnauthenticatedRateLimitedTransport.

The returned Response.Rate value contains the rate limit information from the most recent API call. If a recent enough response isn't available, you can use RateLimits to fetch the most up-to-date rate limit data for the client.

To detect an API rate limit error, you can check if its type is *github.RateLimitError:

repos, _, err := client.Repositories.List(ctx, "", nil)
if _, ok := err.(*github.RateLimitError); ok {
	log.Println("hit rate limit")
}

Learn more about GitHub rate limiting at https://docs.github.com/en/free-pro-team@latest/rest/reference/rate-limit.

Accepted Status

Some endpoints may return a 202 Accepted status code, meaning that the information required is not yet ready and was scheduled to be gathered on the GitHub side. Methods known to behave like this are documented specifying this behavior.

To detect this condition of error, you can check if its type is *github.AcceptedError:

stats, _, err := client.Repositories.ListContributorsStats(ctx, org, repo)
if _, ok := err.(*github.AcceptedError); ok {
	log.Println("scheduled on GitHub side")
}

Conditional Requests

The GitHub API has good support for conditional requests which will help prevent you from burning through your rate limit, as well as help speed up your application. go-github does not handle conditional requests directly, but is instead designed to work with a caching http.Transport. We recommend using https://github.com/gregjones/httpcache for that.

Learn more about GitHub conditional requests at https://docs.github.com/en/free-pro-team@latest/rest/overview/resources-in-the-rest-api#conditional-requests.

Creating and Updating Resources

All structs for GitHub resources use pointer values for all non-repeated fields. This allows distinguishing between unset fields and those set to a zero-value. Helper functions have been provided to easily create these pointers for string, bool, and int values. For example:

// create a new private repository named "foo"
repo := &github.Repository{
	Name:    github.String("foo"),
	Private: github.Bool(true),
}
client.Repositories.Create(ctx, "", repo)

Users who have worked with protocol buffers should find this pattern familiar.

Pagination

All requests for resource collections (repos, pull requests, issues, etc.) support pagination. Pagination options are described in the github.ListOptions struct and passed to the list methods directly or as an embedded type of a more specific list options struct (for example github.PullRequestListOptions). Pages information is available via the github.Response struct.

client := github.NewClient(nil)

opt := &github.RepositoryListByOrgOptions{
	ListOptions: github.ListOptions{PerPage: 10},
}
// get all pages of results
var allRepos []*github.Repository
for {
	repos, resp, err := client.Repositories.ListByOrg(ctx, "github", opt)
	if err != nil {
		return err
	}
	allRepos = append(allRepos, repos...)
	if resp.NextPage == 0 {
		break
	}
	opt.Page = resp.NextPage
}

For complete usage of go-github, see the full package docs.

Integration Tests

You can run integration tests from the test directory. See the integration tests README.

Roadmap

This library is being initially developed for an internal application at Google, so API methods will likely be implemented in the order that they are needed by that application. You can track the status of implementation in this Google spreadsheet.

Contributing

I would like to cover the entire GitHub API and contributions are of course always welcome. The calling pattern is pretty well established, so adding new methods is relatively straightforward. See CONTRIBUTING.md for details.

Versioning

In general, go-github follows semver as closely as we can for tagging releases of the package. For self-contained libraries, the application of semantic versioning is relatively straightforward and generally understood. But because go-github is a client library for the GitHub API, which itself changes behavior, and because we are typically pretty aggressive about implementing preview features of the GitHub API, we've adopted the following versioning policy:

  • We increment the major version with any incompatible change to non-preview functionality, including changes to the exported Go API surface or behavior of the API.
  • We increment the minor version with any backwards-compatible changes to functionality, as well as any changes to preview functionality in the GitHub API. GitHub makes no guarantee about the stability of preview functionality, so neither do we consider it a stable part of the go-github API.
  • We increment the patch version with any backwards-compatible bug fixes.

Preview functionality may take the form of entire methods or simply additional data returned from an otherwise non-preview method. Refer to the GitHub API documentation for details on preview functionality.

License

This library is distributed under the BSD-style license found in the LICENSE file.

Comments
  • Drain Response.Body to enable TCP/TLS connection reuse (4x speedup)

    Drain Response.Body to enable TCP/TLS connection reuse (4x speedup)

    On successful queries (on errors ReadAll runs in CheckResponse), the Response.Body is not read all the way to the EOF as json.Decoder is used, which stops at the end of the object, which is probably followed by a \n.

    Then, Response.Body.Close() is called. When that happens with a non-drained Body, the TCP/TLS connection is closed (which makes sense, in case there was still a lot to read from the network), stopping the Transport from reusing it. Also, a library user can't drain the Body themselves because Close() is called before passing the Response to the user.

    Since we know GitHub API responses only carry a single JSON object, draining before closing is free, and saving all those handshakes causes huge savings in latency, bandwidth and CPU for both the client and the poor GitHub servers.

    Here's the result of running the benchmark below on a ADSL connection:

    before: 2m3.001599093s
    after: 33.753543928s
    
    func main() {
        ts := oauth2.StaticTokenSource(
            &oauth2.Token{AccessToken: os.Getenv("GITHUB_TOKEN")},
        )
        tc := oauth2.NewClient(oauth2.NoContext, ts)
        gh := github.NewClient(tc)
        start := time.Now()
        for i := 0; i < 100; i++ {
            gh.Repositories.Get("FiloSottile", "gvt")
            fmt.Print(".")
        }
        fmt.Printf("\n%s\n", time.Now().Sub(start))
    }
    
  • Consistent Go naming for JSON fields

    Consistent Go naming for JSON fields

    As discussed in https://github.com/google/go-github/pull/520#discussion_r98727959 and https://github.com/google/go-github/pull/602#issuecomment-290255621 the naming of fields such as Total (as opposed to TotalCount) where the JSON name is total_count seems inconsistent and it would be nice to consolidate.

    However, this is a breaking API change.

    This issue has been opened to discuss the situation and see if it is worth breaking the API to have more consistency.

  • int64 IDs

    int64 IDs

    On 32-bit platforms, a Go int is an int32.

    I worry about the use of int as the type for Github IDs in the go-github package.

    Is there documentation to suggest that Github IDs are limited to 2 billion items? Seems unlikely. But I can't find anything.

    I propose we keep "Number" fields as int, but change all the ID fields to be int64.

    Thoughts?

    /cc @gmlewis @willnorris @shurcooL

  • Support `auto_merge` field in PullRequest struct

    Support `auto_merge` field in PullRequest struct

    The pulls API returns an auto_merge field which is currently not available in the PullRequest struct.

    When auto-merge is enabled for a Pull-Request the returned auto_merge field looks like:

      "auto_merge": {
        "enabled_by": {
          "login": "fho",
          "id": 514535,
          "node_id": "MDQ6VXNlcjUxNDUzNQ==",
          "avatar_url": "https://avatars.githubusercontent.com/u/514535?v=4",
          "gravatar_id": "",
          "url": "https://api.github.com/users/fho",
          "html_url": "https://github.com/fho",
          "followers_url": "https://api.github.com/users/fho/followers",
          "following_url": "https://api.github.com/users/fho/following{/other_user}",
          "gists_url": "https://api.github.com/users/fho/gists{/gist_id}",
          "starred_url": "https://api.github.com/users/fho/starred{/owner}{/repo}",
          "subscriptions_url": "https://api.github.com/users/fho/subscriptions",
          "organizations_url": "https://api.github.com/users/fho/orgs",
          "repos_url": "https://api.github.com/users/fho/repos",
          "events_url": "https://api.github.com/users/fho/events{/privacy}",
          "received_events_url": "https://api.github.com/users/fho/received_events",
          "type": "User",
          "site_admin": false
        },
        "merge_method": "rebase",
        "commit_title": "",
        "commit_message": ""
      },
    

    It would be great if go-github could parse this field and make it accessible.

  • Add function for PullRequestService to download raw content of pull r…

    Add function for PullRequestService to download raw content of pull r…

    …equest

    We already has an issue here https://github.com/google/go-github/issues/6 And as @willnorris said it's better to use Contents API to download, but Contents API seems to support blob or file content which is a part of a repository git tree only. (not include pull request)

    I want to support patch/diff media type in pull request also (which may not be supported even in future release). So i added method GetRaw to PullRequestService separate from original Get method (to maintain backward compatibility)

  • #720 Initial commit for listing Plans and Plan Accounts

    #720 Initial commit for listing Plans and Plan Accounts

    • Includes basic testing for Listing Plans and the Accounts linked to a Plan (including stubs)

    NOTE This is currently awaiting scrutiny as it's my first contribution to the project. I would appreciate any feedback (good or bad) and the 👍 if it's ok to carry on with the rest of the implementation for #720

  • Update integration tests for new branch protection API.

    Update integration tests for new branch protection API.

    Integration tests update branches were broken since old structures were used. This has been modified. Integration folder requires ProtectionRequest structure to be available by RepositoryService. Protection also has been changed.

    Resolves #507. Updates #310.

  • Repositories.ListCommitActivity throwing Unmarshal error:

    Repositories.ListCommitActivity throwing Unmarshal error:

    json: cannot unmarshal object into Go value of type []*github.WeeklyCommitActivity

    more info: *encoding/json.UnmarshalTypeError {Value: "object", Type: reflect.Type(*reflect.rtype) *{size: 24, ptrdata: 8, hash: 3339529106, tflag: tflagExtraStar (2), align: 8, fieldAlign: 8, kind: 23, equal: nil, gcdata: *1, str: 78188, ptrToThis: 93696}, Offset: 1, Struct: "", Field: ""}

    code used was simple: ws, _, err := client.Repositories.ListCommitActivity(ctx, owner, repo)

    OS: MacOS 12.1 Chip: Apple M1 Golang version: 1.19.2

  • github actions date not getting parsed by go-github

    github actions date not getting parsed by go-github

    github actions log:

    19:45:30 main.go:110: parsing time ""8/18/2019 7:44:51 PM"" as ""2006-01-02T15:04:05Z07:00"": cannot parse "/2019 7:44:51 PM"" as "2006"
    ##[error]Docker run failed with exit code 1
    

    this is on line 110, github.ParseWebHook , it's working with any other payload if I just use it from a regular curl command. but it's failing when used with GithubActions.

    data, err := ioutil.ReadFile(cmClient.inputFilePath)
    if err != nil {
    	log.Fatalln(err)
    }
    // Parsing event.json.
    event, err := github.ParseWebHook("issue_comment", data)
    if err != nil {
    	log.Fatalln(err)
    }
    

    data == issue_comment payload

    not sure if this is a github action issue or go-github issue. how can i help to resolve this?

  • Support PubSubHubbub API for creating hooks

    Support PubSubHubbub API for creating hooks

    Are there any plans to support the PubSubHubbub API for creating webhooks?

    I could try to create a PR for implementing this (I'm hoping to use it for implementing https://github.com/terraform-providers/terraform-provider-github/issues/275) if there is any chance of it being accepted.

  • Support preview Installations API - updated routes for adding or removing a repository

    Support preview Installations API - updated routes for adding or removing a repository

    GitHub Developers announcment: https://developer.github.com/changes/2017-06-30-installations-adding-removing-a-repository/

    GitHub API docs: https://developer.github.com/v3/apps/installations/#add-repository-to-installation

  • Add support for GitHub Environments for Pro/Teams pricing plans

    Add support for GitHub Environments for Pro/Teams pricing plans

    The PR fixes the issue reported on https://github.com/google/go-github/issues/2602

    In June GitHub made the environments and environment protection rules generally available, however, the wait_timer and reviewers remain limited to enterprise.

    Code was written to send wait_timer and reviewers with default values if no value is present, so existing settings can be cleared. Due to this, the code was returning 422 when called to create environments for Pro/Team private repos, as these parameters are only supported for enterprise or public repos.

    PR intends to handle the error with a retry when the following conditions are met:

    • error code is 422
    • wait_timer is the default value (0)
    • reviewers is the default value ([])

    When retrying the call, a new object is sent, which only contains the parameters that are accepted for Pro/Teams private repos.

  • Deployment Branch Policies is not implemented

    Deployment Branch Policies is not implemented

    Deployment branch policies endpoints are not implemented. Docs: https://docs.github.com/en/rest/deployments/branch-policies?apiVersion=2022-11-28.

    I want to implement this and any guidance on where this should end up? I am guessing under Actions as that is the required permission to access this

  • Repository environment creation fails on private Teams repos

    Repository environment creation fails on private Teams repos

    This is related to the discussion on the https://github.com/integrations/terraform-provider-github/issues/1262

    In June GitHub made the environments and environment protection rules generally available, however, the wait_timer and reviewers remains limited to enterprise.

    Many developers would like to make use of this great new feature, but the bug in the Terraform provider currently proves to be a blocker. The provider uses the go-github Go library under the hood and makes the following call:

    _, _, err := client.Repositories.CreateUpdateEnvironment(ctx, owner, repoName, escapedEnvName, &updateData)
    

    where the &updateData is a github.CreateUpdateEnvironment struct.

    Looking at the code it seems that instead of sending nil value for wait_timer it defaults to 0.

    // CreateUpdateEnvironment represents the fields required for the create/update operation
    // following the Create/Update release example.
    // See https://github.com/google/go-github/issues/992 for more information.
    // Removed omitempty here as the API expects null values for reviewers and deployment_branch_policy to clear them.
    type CreateUpdateEnvironment struct {
    	WaitTimer              *int            `json:"wait_timer"`
    	Reviewers              []*EnvReviewers `json:"reviewers"`
    	DeploymentBranchPolicy *BranchPolicy   `json:"deployment_branch_policy"`
    }
    

    This is causing the issue for us, as the API doesn't expect this parameter and returns 422.

    I understand why the omitempty was removed, so I'm looking at what alternative solutions are possible to ensure environments fully work regardless of the payment plan.

  • Add go generate mention to CONTRIBUTING.md

    Add go generate mention to CONTRIBUTING.md

    a WIP for the improvement of CONTRIBUTING.md as detailed by #2579 , mentioning the existence of generated files and the fact that they should be added alongside the manual part of the commit. We could probably add a few more things, but those will come along if suggestions do.

  • Support new Audit Log fields for Dependabot Alerts

    Support new Audit Log fields for Dependabot Alerts

    GitHub Announcement: https://github.blog/changelog/2022-11-29-audit-log-improvements-for-dependabot-alerts/ New fields: alert_number, ghsa_id, dismiss_reason, and dismiss_comment.

    This would be a great PR for any new contributor to this repo or a new Go developer. All contributions are greatly appreciated!

    Feel free to volunteer for any issue and the issue can be assigned to you so that others don't attempt to duplicate the work.

    Please check out our CONTRIBUTING.md guide to get started. (In particular, please remember to go generate ./... and don't use force-push to your PRs.)

    Thank you!

Go library for accessing the GitHub API

go-github go-github is a Go client library for accessing the GitHub API v3. Currently, go-github requires Go version 1.9 or greater. go-github tracks

Dec 30, 2022
Go library for accessing trending repositories and developers at Github.
Go library for accessing trending repositories and developers at Github.

go-trending A package to retrieve trending repositories and developers from Github written in golang. This package were inspired by rochefort/git-tren

Dec 21, 2022
Go library for accessing the MyAnimeList API: http://myanimelist.net/modules.php?go=api

go-myanimelist go-myanimelist is a Go client library for accessing the MyAnimeList API. Project Status The MyAnimeList API has been stable for years a

Sep 28, 2022
A GoLang wrapper for Politics & War's API. Forego the hassle of accessing the API directly!

A GoLang wrapper for Politics & War's API. Forego the hassle of accessing the API directly!

Mar 5, 2022
Go library for accessing the Codeship API v2

Codeship API v2 Client for Go Codeship API v2 client for Go. Documentation https://godoc.org/github.com/codeship/codeship-go Usage go get -u github.co

Sep 27, 2022
Go library for accessing the Keycloak API

keycloak keycloak is a Go client library for accessing the Keycloak API. Installation go get github.com/zemirco/keycloak Usage package main import (

Dec 1, 2022
NotionGo is a Go client library for accessing the Notion API v1.

NotionGo (WIP) NotionGo is a Go client library for accessing the Notion API v1. Installation NotionGo is compatible with modern Go releases in module

May 22, 2021
go-ftx go-ftx is a Go client library for accessing the FTX API

go-ftx go-ftx is a Go client library for accessing the FTX API

Nov 14, 2022
Go library for accessing the BlaBlaCar API

go-blablacar is a Go client library for accessing the BlaBlaCar API.

Nov 27, 2022
Go(lang) client library for accessing information of an Apache Mesos cluster.

megos Go(lang) client library for accessing an Apache Mesos cluster. Features Determine the Mesos leader Get the current state of every mesos node (ma

Sep 27, 2022
🤖🚀📦 A Discord Bot for accessing the cdnjs platform
🤖🚀📦 A Discord Bot for accessing the cdnjs platform

A bridge between https://cdnjs.com/api and Discord Big shoutout to Br1ght0ne for helping me with writing helpers.go/SplitIn

Aug 17, 2022
efsu is for accessing AWS EFS from your machine without a VPN

efsu: VPN-less access to AWS EFS efsu is for accessing AWS EFS from your machine without a VPN. It achieves this by deploying a Lambda function and sh

Mar 11, 2022
A GitHub CLI extension that displays collaboration-related information about a GitHub repository.
A GitHub CLI extension that displays collaboration-related information about a GitHub repository.

collab-scanner GitHub CLI extension A GitHub CLI extension that displays collaboration-related information on a repository. Install gh extension insta

Dec 30, 2022
This project is mostly a fancy wrapper around the Extract Table (github) API

Knockout-City-Stat-Scanner Credits This project is mostly a fancy wrapper around the Extract Table (github) API, they did all the heavy lifting here a

Jan 30, 2022
API Статистики пользователя GitHub 🐙

?? API статистики пользоватя GitHub ?? ???? English Version ???? Commits Request sample GET https://hud0shnikgitapi.herokuapp.com/commits/hud0shnik GE

Oct 24, 2022
Simple-Weather-API - Simple weather api app created using golang and Open Weather API key
Simple-Weather-API - Simple weather api app created using golang and Open Weather API key

Simple Weather API Simple weather api app created using golang and Open Weather

Feb 6, 2022
go-whatsapp-rest-API is a Go library for the WhatsApp web which use Swagger as api interface

go-whatsapp-rest-API go-whatsapp-rest-API is a Go library for the WhatsApp web which use Swagger as api interface Multi-devices (MD) Support. This ver

Dec 15, 2022
:fishing_pole_and_fish: Webhook receiver for GitHub, Bitbucket, GitLab, Gogs

Library webhooks Library webhooks allows for easy receiving and parsing of GitHub, Bitbucket and GitLab Webhook Events Features: Parses the entire pay

Jan 4, 2023
Periodically collect data about my Twitter account and check in to github to preserve an audit trail.

Twitter audit trail backup This repository backs up my follower list, following list, blocked accounts list and muted accounts list periodically using

Dec 28, 2022