Categorygithub.com/willabides/octo-go
modulepackage
0.8.0
Repository: https://github.com/willabides/octo-go.git
Documentation: pkg.go.dev

# README

octo-go

godoc ci

octo-go is an experimental client for GitHub's v3 API. It is generated from the openapi schema published at https://github.com/github/rest-api-description

Project status: Experimental

Overview

For every API endpoint, octo-cli provides a request struct and a response struct. The request struct is used to build the http request, and the response struct is used to handle the api's response. You can use these structs as-is and handle all the http details yourself, or you can let octo-go do the request for you as well. Each endpoint also has a function that accepts the endpoints request struct and returns the response struct.

Let's use the issues/create endpoint as an example. You would use issues.CreateReq to build your request.

You can build a request like this:

req := issues.CreateReq{
    Owner: "myorg",
    Repo:  "myrepo",
    RequestBody: issues.CreateReqBody{
        Title: octo.String("hello world"),
        Body:  octo.String("greetings from octo-cli"),
        Labels: []string{"test", "hello-world"},
    },
}

Then you can perform the request with:

resp, err := issues.Create(ctx, &req)

And finally get the id of the newly created issue with:

issueID := resp.Data.Id

User Agent

GitHub requires all requests have a User-Agent header set. Octo-go sets it to octo-go by default, but please set it to the name of your program instead. Do that with the option octo.WithUserAgent("my wonderful computer program").

Authentication

In most situations, octo-go can handle the authentication, but you can also provide your own transport to set the Authentication header if you want.

Personal Access Token

This is the simplest and most common way to authenticate.

myToken := os.Getenv("GITHUB_TOKEN") // or however you want to provide your token

client := octo.NewClient(octo.WithPATAuth(myToken))

GitHub App

If you want to authenticate as a GitHub App, octo can do that for you too. You need to provide the app's private key in PEM format along with your app's ID.

appID := int64(1)
key, err := ioutil.ReadFile("appsecretkey.pem")
if err != nil {
    log.Fatal(err)
}
client := octo.NewClient(octo.WithAppAuth(appID, key))

GitHub App Installation

To authenticate as a GitHub App Installation, you need the installation's ID along with the app's ID and private key.

appID := int64(1)
installationID := int64(99)
key, err := ioutil.ReadFile("appsecretkey.pem")
if err != nil {
    log.Fatal(err)
}

instTokenClient := octo.NewClient(octo.WithAppAuth(appID, key))

auth := octo.WithAppInstallationAuth(installationID, instTokenClient, nil)
client := octo.NewClient(auth)

When authenticating as an App Installation, you can also limit the token's authorization to specific repositories and scopes by setting the request body used to create the token.

appID := int64(1)
installationID := int64(99)
repoID := int64(12)
key, err := ioutil.ReadFile("appsecretkey.pem")
if err != nil {
    log.Fatal(err)
}

instTokenClient := octo.NewClient(octo.WithAppAuth(appID, key))

auth := octo.WithAppInstallationAuth(installationID, instTokenClient, &apps.CreateInstallationAccessTokenReqBody{
    Permissions: map[string]string{
        "deployments": "write",
        "content":     "read",
    },
    RepositoryIds: []int64{repoID},
})
client := octo.NewClient(auth)

Pagination

The GitHub API supports paging through result sets using relative links in the Link header. Octo-go makes use of these headers to enable paging. Every response has the methods RelLink(lnk string) and HasRelLink(lnk string) to get relative links. You can call this with RelNext for the next page of results, RelPrev for the previous page. RelFirst and RelLast point the first and last page of results.

Every request has a Rel(lnk string, resp *ResponseType) method that will update the request to point to a response's relative link.

Let me demonstrate with an example. getReleaseBlockers will page through all open golang/go issues that are labeled "release-blocker" and return their titles.

func getReleaseBlockers(ctx context.Context, client octo.Client) ([]string, error) {
	var result []string

	// Build the initial request.
	req := &issues.ListForRepoReq{
		Owner:  "golang",
		Repo:   "go",
		Labels: octo.String("release-blocker"),
	}

	// ok will be true as long as there is a next page.
	for ok := true; ok; {
		// Get a page of issues.
		resp, err := client.Issues().ListForRepo(ctx, req)
		if err != nil {
			return nil, err
		}

		// Add issue titles to the result.
		for _, issue := range resp.Data {
			result = append(result, issue.Title)
		}

		// Update req to point to the next page of results.
		// If there is no next page, req.Rel will return false and break the loop
		ok = req.Rel(octo.RelNext, resp)
	}
	return result, nil
}

Rate Limits

The GitHub API has a general rate limit of 5,000 requests per hour for most authenticated requests and 60 per hour per ip address for unauthenticated requests. More details are in the API documentation.

The API includes rate limit information in response headers, and octo-go provides three helper functions:

octo.RateLimitRemaining() - returns the number of requests remaining (or -1 if the header is missing)

octo.RateLimitReset() - returns the time when the rate limit will reset (or zero value if the header is missing)

octo.RateLimit() - returns the rate limit (or -1 if the header is missing)

You can also explicitly get your rate limit status with ratelimit.Get()

# Packages

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Functions

Bool returns a pointer to b.
Int64 returns a pointer to i.
ISOTimeString returns a pointer to tm formated as an iso8601/rfc3339 string.
NewClient returns a new Client.
RateLimit - The maximum number of requests you're permitted to make per hour.
RateLimitRemaining - The number of requests remaining in the current rate limit window.
RateLimitReset - X-RateLimit-Reset returns time.Zero if no X-RateLimit-Reset value exists in the response header.
RelLink returns the content of lnk from the response's Link header or "" if it does not exist.
String returns a pointer to s.
WithAllPreviews enables all previews that are available for your request.
WithAppAuth provides authentication for a GitHub App.
WithAppInstallationAuth provides authentication for a GitHub App installation client is the client to use when fetching the installation token.
WithAuthProvider sets a provider to use in setting the Authentication header This is for custom providers.
WithBaseURL set the baseURL to use.
WithHTTPClient sets an http client to use for requests.
WithPATAuth authenticates requests with a Personal Access Token.
WithRequiredPreviews enables any previews that are required for your request.
WithUserAgent sets the User-Agent header in requests.

# Constants

Common values for rel links.
Common values for rel links.
Common values for rel links.
Common values for rel links.

# Interfaces

ResponseError is an error from an *http.Response.

# Type aliases

Client is a set of options to apply to requests.