Overview
If you code, you're probably already familiar with GitHub. It is one of the most popular solutions available for source code management. It provides extensive features that meet almost all common needs.
What many don't know is that it also provides a fairly robust API for accessing those features programmatically. This article will provide C# coding examples to introduce some of the more common features of that API.
Thankfully, the folks at GitHub have already created a NuGet package, named Octokit, to do most of the heavy lifting for GitHub API V3. While it is not quite perfect yet, it does get the job done.
Additionally, GitHub is currently (2/6/2019) beta testing a new framework, named Octokit.GraphQL.net, for GitHub API V4. However, this is beyond the scope of this article. For those who want to follow its progress, a link to its GitHub repository is provided in the "Further Reading" section of this article.
UPDATE: As of August 13, 2021, GitHub no longer supports the "Basic Authentication" mechanism described in this article and available in the demo application. For additional details see the following link:
https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/
Sample Applications
The source code for two sample applications is included with this article:
- GitHubApiSnippets.sln – This Windows Console application contains all of the sample code included with this article. The source code for this application can be downloaded from the following location: GitHubApiSnippets.zip.
- GitHubApiDemo.sln – This Windows form application allows the user to experiment with GitHub API searches without writing code. The source code for this application can be downloaded from the following location: GitHubApiDemo.zip.
Both of these applications are licensed under CPOL.
Both of these applications were developed and built using Visual Studio 2017 Professional. However, they should also be compatible with Visual Studio 2017 Community and any later versions of Visual Studio.
A more detailed description of both applications is provided at the end of this article.
Getting Started
To use the GitHub API, an application must first connect to it. There are three common ways to connect: unauthenticated access, basic authentication, and OAuth token authentication. With all of these connection types, the GitHub API will limit the frequency of requests and separately limit the frequency and size of searches.
Client Identity
In all cases, the client needs to identify itself. This is done by providing a simple textual identity. The text should be one of the following (in order of preference): the name of the product, the GitHub organization, or the GitHub username. The following code provides an example.
var productInformation = new ProductHeaderValue(GitHubIdentity);
Rate Limits
The GitHub API does impose some strict limits on the frequency of requests. Authenticated users are limited to 5,000 requests per hour. Unauthenticated users are limited to 60 requests per hour. Administrators of GitHub Enterprise servers can adjust these rate limits on a per-user and per-application basis. For more information, see "GitHub Enterprise – Configuring Rate Limits" in the "Further Reading" section of this article.
Search Limits
The GitHub API also imposes separate limits on search requests. Authenticated users are limited to 30 search requests per minute. Unauthenticated users are limited to 10 search requests per minute. Individual searches are also limited by the number of items they will return. A search, which may be broken into multiple requests/pages, is limited to a maximum of 1,000 items.
Unauthenticated Access
The simplest means of access is via an unauthenticated client. However, this type of client has the least access and the most restrictive rate limits. It is not recommended, except to create an OAuth token. The following code provides an example.
var productInformation = new ProductHeaderValue(GitHubIdentity);
var client = new GitHubClient(productInformation);
Basic Authentication
To create a client using basic authentication, the application shares a username and a password with GitHub. This is a simple means of authentication. It is the one most likely used by desktop applications. Its sole disadvantage is that the application is at least temporarily aware of the user’s GitHub credentials. For web applications, OAuth token authentication is recommended. The following code provides an example of basic authentication.
var productInformation = new ProductHeaderValue(GitHubIdentity);
var credentials = new Credentials(username, password, AuthenticationType.Basic);
var client = new GitHubClient(productInformation) { Credentials = credentials };
OAuth Token Authentication
With OAuth, a user authenticates using a token that was issued by the GitHub web site. It has the advantage that the application is never aware of the user’s GitHub credentials. Once the token is available, the connection process is very simple and similar to basic authentication. The following code provides an example.
var productInformation = new ProductHeaderValue(GitHubIdentity);
var credentials = new Credentials(token);
var client = new GitHubClient(productInformation) { Credentials = credentials };
The complexity of this approach arises from the necessity to create an OAuth token. For the purposes of command-line applications, it is possible for a user to directly create an access token. To do this, follow the instructions here: https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/.
However, this is not recommended for web applications. Instead, web applications should use the OAuth web application flow described below.
OAuth Web Application Flow
The place where OAuth is strongest is with web applications. In this instance, you don’t start with an OAuth token. Instead, the application allows the GitHub web site to authenticate the user. The application then requests a token for that user. After the token is available, the connection process is exactly as was previously described.
The process is a little bit complicated and beyond the scope of this article, but we’ll at least provide a quick overview and a link to a very detailed description. Basically, the flow is as follows:
- You register your application with GitHub and receive a client identity and a client secret. This is a one-time thing. Once the application has been registered you "bake" the identity and secret into your application’s code.
- Your application re-directs to a GitHub URL, specifying a randomly generated key and the requested permissions. The randomly generated key helps to prevent cross-site request forgeries.
- GitHub authenticates the user.
- The GitHub URL re-directs back to your web site providing the same randomly generated key and an authentication code.
- Your application confirms the randomly generated key. It then creates an authentication code by specifying the client’s identity, the client’s secret, and the authentication code.
- In return, your application receives an OAuth token used to authenticate, as previously described.
The code to request a token is as follows:
var client = new GitHubClient(new ProductHeaderValue(GitHubIdentity));
OauthToken tokenInfo = await client.Oauth.CreateAccessToken(
new OauthTokenRequest(clientId, clientSecret, authenticationCode));
string token = tokenInfo.AccessToken;
The following link, on Phil Haack’s blog, provides a detailed description of the OAuth web application flow and also provides a sample project: https://haacked.com/archive/2014/04/24/octokit-oauth/.
GitHub Enterprise
Connecting to a GitHub Enterprise instance is nearly identical to what was previously described. One simply provides an additional parameter: the URL of the GitHub Enterprise server.
var client = new GitHubClient(productInformation, new Uri(enterpriseUrl))
{
Credentials = credentials
};
Top-level Information
If one already knows the identity of the information that is required, Octokit often provides methods to directly access it. Otherwise, it may be necessary to search for that information using the Search
property of the client.
This section of the article will discuss some common top-level items of information. Sometimes the information is subordinate to the top-level information (e.g. a fork is subordinate to a repository).
In this case, there is still generally a subordinate property (in the client) that will allow one to directly access the information, without searching. The "GitHubClient Properties" section of this article provides an overview of these subordinate properties.
Repository
To access a repository directly, without first searching for it, use the Get
method. For example, to get the "octokit/octokit.net" repository:
Repository repository = await client.Repository.Get("octokit", "octokit.net");
Repository Forks
The same Repository
property of the client also provides access to subordinate information for that repository. So, for example, the following code gets all of the forks for the "octokit/octokit.net" repository:
IReadOnlyList<Repository> allForks = await client.Repository.Forks.GetAll(
"octokit", "octokit.net");
Repository Forks (with Paging)
While the previous code works well for a small number of items, it will fail if the number of items grows too large. Most of the "get" methods, which return large numbers of items, support an optional parameter (of type ApiOptions
). This parameter allows the caller to get the results in smaller chunks (or pages).
The code in the following example also gets all of the forks for the "octokit/octokit.net" repository, but this time paging is implemented:
var options = new ApiOptions { PageCount = 1, PageSize = 100, StartPage = 1 };
int maximumCount = options.PageCount.Value * options.PageSize.Value;
Console.WriteLine("Repository.Forks.GetAll (Paging):");
while (true)
{
IReadOnlyList<Repository> forks = await client.Repository.Forks.GetAll(
"octokit", "octokit.net", options);
foreach (Repository fork in forks)
Console.WriteLine($" {fork.Owner.Login}/{fork.Name}");
if (forks.Count < maximumCount)
break;
options.StartPage++;
}
User
To access a user directly, without first searching for it, use the Get
method as follows:
User user = await client.User.Get("octokit");
This same method gets users with both personal and organization account types.
Searching
The Octokit framework provides comparatively robust searching capabilities. The API can search for code/files, issues/pull requests, labels, repositories, and users/organizations.
The results of a search are broken into pages. Each call to one of these methods will return a single page of results which, by default, consists of between zero and 100 items.
This section of the article provides a quick overview and an example of how paging can be implemented. A more detailed description of the search criteria is provided later in the article, in the "Search Property" section.
Code
Sometimes it is necessary to search for a file within a repository. In these cases, the SearchCode
method is used to find files.
Searching for Files
The following is a simple search request that finds the first 100 C# files, in the "octokit/octokit.net" repository, which contain the text "issue" in the file path.
SearchCodeResult result = await client.Search.SearchCode(
new SearchCodeRequest("issue")
{
In = new CodeInQualifier[] { CodeInQualifier.Path },
Language = Language.CSharp,
Repos = new RepositoryCollection { "octokit/octokit.net" }
});
Searching for Files (with Paging)
Sometimes it is necessary to find more than 100 items. The Octokit framework allows up to 1000 items to be found. To use this feature, it is necessary to implement paging, which is accomplished as follows:
const int MaximumSearchItems = 1000;
var request = new SearchCodeRequest
{
Language = Language.CSharp,
Repos = new RepositoryCollection { "octokit/octokit.net" }
};
int maximumPage = MaximumSearchItems / request.PerPage;
for(request.Page = 1; request.Page <= maximumPage; request.Page++)
{
SearchCodeResult result = await client.Search.SearchCode(request);
if (request.Page == 1)
Console.WriteLine($"Search.SearchCode (Paging): TotalCount={result.TotalCount}");
foreach (SearchCode code in result.Items)
Console.WriteLine($" {code.Path}");
if (result.IncompleteResults || result.Items.Count < request.PerPage)
break;
}
Issue
Sometimes it is necessary to search for issues within a repository. In these cases, the SearchIssue
method is used to find issues.
The following is a simple search request that finds the first 100 issues, for the "octokit/octokit.net" repository, which contain the text "bug" in the title.
SearchIssuesResult result = await client.Search.SearchIssues(
new SearchIssuesRequest("bug")
{
In = new IssueInQualifier[] { IssueInQualifier.Title },
Repos = new RepositoryCollection { "octokit/octokit.net" }
});
Label
Sometimes it is necessary to search for labels within a repository. In these cases, the SearchLabel
method provides a limited ability to find labels.
The following is a simple search request that finds the first 100 labels, for the "octokit/octokit.net" repository, which start with the text "category".
Repository repository = await client.Repository.Get("octokit", "octokit.net");
SearchLabelsResult result = await client.Search.SearchLabels(
new SearchLabelsRequest("category", repository.Id));
Repository
Sometimes it is necessary to search for repositories. In these cases, the SearchRepo
method is used to find repositories.
The following is a simple search request that finds the first 100 repositories that contain the text "octokit" in the repository name.
SearchRepositoryResult result = await client.Search.SearchRepo(
new SearchRepositoriesRequest("octokit")
{
In = new InQualifier[] { InQualifier.Name }
});
User
Sometimes it is necessary to search for a user or organization. In these cases, the SearchUser
method is used to find users or organizations.
The following is a simple search request that finds the first 100 users (of account type User) that contain the text "oct" in one of the default fields (user’s login name, full name, or e-mail address).
SearchUsersResult result = await client.Search.SearchUsers(
new SearchUsersRequest("oct")
{
AccountType = AccountSearchType.User
});
Note: By specifying an account type of Org
, a similar search could be conducted for organizations instead of personal users.
GitHubClient Properties
To a large extent, a GitHub client (GitHubClient
) is organized into a hierarchy of properties, each of which provides a separate interface, related to an individual element of the GitHub object model.
So, for example, to access a GitHub repository, one would reference the Repository
property, to obtain access to the related API (IRepositoriesClient
), as follows:
Repository repository = await client.Repository.Get("octokit", "octokit.net");
To access a subordinate element of a repository (e.g. a branch) one would reference the nested Repository.Branch
property, to obtain access to the related API (IRepositoryBranchesAPI
), as follows:
Branch branch = await client.Repository.Branch.Get("octokit", "octokit.net", "master");
There are a couple of exceptions to this pattern. One exception is the previously discussed Search
property, which provides access to the search API (ISearchClient
). Another exception is the Miscellaneous
property, which provides access to the miscellaneous API (IMiscellaneousClient
). Both of these APIs deal with multiple elements of the object model.
The following table provides an overview of the hierarchy of GitHubClient
properties, which provide access to the related APIs.
Member Name | Description |
Activity | Manage the "social" aspects of GitHub, like events, Atom Feeds, notifications of comments, starring of repositories, and events for repositories that are watched. |
| Events | List the events that occurred for various GitHub entities (e.g. organizations and repositories). |
| Feeds | List the Atom feeds that are available to the authenticated user. |
| Notifications | List notifications for conversations and comments, mark them as read, and manage the authenticated user’s subscriptions to them. |
| Starring | Manage starring (bookmarking) for repositories and list information about bookmarked repositories. |
| Watching | Register for notifications of discussions and events related to selected repositories. |
Authorization | Manage authorizations (grant, revoke, etc.) for a user, organization, or application. |
Check | Manage checks runs/suites for commits and get results from them. |
| Run | Manage check runs for commits and get results from those check runs. |
| Suite | Manage a suite of check runs for commits and get results from those suites. |
Enterprise | Manage a GitHub enterprise and list information about it. |
| AdminStats | List administrative statistics (mostly global counters) for a GitHub enterprise. |
| Ldap | Manage synchronizations of GitHub enterprise users and teams with an LDAP server. |
| License | Get licensing information for the GitHub enterprise. |
| Organization | Create organizations (e.g. departments) for the GitHub enterprise. |
| PreReceiveEnvironment | Manage pre-receive environments for the GitHub enterprise. |
| SearchIndexing | Queue search indexing jobs for the GitHub enterprise. |
Gist | Manage GitHub Gists (code snippets, notes, to-do lists, etc.). |
| Comment | Manage comments for Gists. |
Git | More directly access a Git database on GitHub (e.g. read/write raw Git objects). |
| Blob | Manage blobs (binary large objects) within a Git database. |
| Commit | Manage Git commits within a Git database. |
| Reference | Manage Git references within a Git database. |
| Tag | Manage Git tags within a Git database. |
| Tree | Manage Git trees within a Git database. |
GitHubApps | Get information about GitHub applications and installations of the application. |
| Installation | Get information about the installations of GitHub applications. |
Issue | Manage and list issues (bug reports, suggested improvements, questions, etc.) for repositories. |
| Assignee | Manage and list the users assigned to an issue. |
| Comment | Manage and list the comments associated with an issue. |
| Events | List the events associated with an issue. |
| Labels | Manage and list the labels associated with an issue. |
| Milestones | Manage and list the milestones associated with an issue. |
| Timelines | Manage and list the timeline events associated with an issue. |
Migration | Manage and list migrations between GitHub and an external system. |
| Migrations | Manage and list migrations between GitHub and an external system. |
Miscellaneous | List miscellaneous information and meta-data that isn’t covered in one of the other APIs (e.g. available emojis). |
OAuth | Create OAuth (Open Authorization) access tokens and get the GitHub login URL. |
Organization | Manage and list organizations (groups of users). |
| Member | Manage and list members (users) belonging to an organization. |
| OutsideCollaborator | Manage and list outside collaborators (users) for an organization. |
| Team | Manage and list teams (groups of users) for an organization. |
PullRequest | Manage and list pull requests for a repository. |
| Review | Manage and list reviews for a pull request. |
| ReviewComment | Manage and list review comments for a pull request. |
| ReviewRequest | Manage and list review requests for a pull request. |
Reaction | Manage and list reactions to commit comments, issues, issue comments, and pull request review comments. A reaction is simple user feedback that provides an indication of approval or disapproval (e.g. thumbs up, thumbs down, confused, etc.). |
| CommitComment | Manage and list reactions for a commit comment. |
| Issue | Manage and list reactions for an issue. |
| IssueComment | Manage and list reactions for an issue comment. |
| PullRequestReviewComment | Manage and list reactions to a pull request review comment. |
Repository | Manage and list repositories. |
| Branch | Manage and list branches for a repository. |
| Collaborator | Manage and list users who collaborate on a repository. |
| Comment | Manage and list comments associated with a repository. |
| Commit | List and compare commits associated with a repository. |
| Content | Manage and list the content (files, etc.) associated with a repository. |
| DeployKeys | Manage and list deployment keys associated with a repository. |
| Deployment | Manage and list deployments for a repository. |
| | Status | Manage and list the statuses for a repository’s deployments. |
| Forks | Manage and list the forks for a repository. |
| Hooks | Manage and list the webhooks (subscriptions to events) for a repository. |
| Invitation | Manage and list the users invited to collaborate on a repository. |
| Merging | Merge branches in a repository. |
| Page | List and build web pages for a repository. |
| Project | Manage and list project boards for repositories or organizations. It is worth noting that the placement of this particular API under the repository API is unusual, since a project board created for an organization would not necessarily have a related repository. |
| | Card | Manage and list the cards (annotated issues/pull requests) for a project board. |
| | Column | Manage and list the columns for a project board. Columns are used to group related project cards. |
| PullRequest | Manage and list pull requests for a repository. |
| | Review | Manage and list reviews for a pull request. |
| | ReviewComment | Manage and list review comments for a pull request. |
| | ReviewRequest | Manage list review requests for a pull request. |
| Release | Manage and list releases for a repository. |
| Statistics | Get the statistics (mostly counters) for a repository. |
| Status | Manage the statuses for a repository reference (branch, tag, etc.). |
| Traffic | List traffic/usage statistics (and information) for a repository. |
Search | Search for GitHub entities like code, issues/pull requests, labels, repositories, and users/organizations. |
User | Manage and list users. |
| Administration | Manage (create, delete, etc.) users and list some administrative information about users. |
| Emails | Manage and list the e-mail addresses for the authenticated user. |
| Followers | Manage and list the other users who follow a user. |
| GitSshKey | Manage and list the public keys (SSH/Secure Shell) for a user. |
| GpgKey | Manage and list the GPG (GNU Privacy Guard) keys for a user. |
While it is beyond the scope of an introductory article to cover the entirety of the Octokit.net framework, the remainder of this article will provide a brief overview of some selected properties from the above table.
Issue Property
To access an issue directly, without first searching for it, use the Get
method. For example, to get issue number 1 in the "octokit/octokit.net" repository:
Issue issue = await client.Issue.Get("octokit", "octokit.net", 1);
Repository Property
To access a repository directly, without first searching for it, use the Get
method. For example, to get the "octokit/octokit.net" repository:
Repository repository = await client.Repository.Get("octokit", "octokit.net");
The same Repository
property of the client also provides access to subordinate information for that repository. So, for example, the following code gets the "master" branch of the "octokit/octokit.net" repository:
Branch branch = await client.Repository.Branch.Get("octokit", "octokit.net", "master");
Search Property
The Search
property provides access to the ISearchClientAPI
interface, which supports searching of five different entities: code/files, issues/pull requests, labels, repositories, and users/organizations. The methods used to retrieve each of these entities are SearchCode
, SearchIssues
, SearchLabels
, SearchRepo
, and SearchUsers
.
Each of these methods accepts a parameter, which is derived from the BaseSearchRequest
class, to specify the search criteria. The results of a search are divided into one or more pages of search results.
Each call to one of these methods will return a single page of results which, by default, consists of between zero and 100 items.
Before retrieving the first page, it is possible to adjust the maximum number of items (in each page), by setting the PerPage
property. To advance to subsequent pages of results, simply increment the Page
property and make a subsequent call with the same criteria.
The common properties across all types of searches, present in the BaseSearchRequest
class, are as follows:
Property | Description |
Order | The order in which items are sorted (ascending or descending). |
Page | The one-based page number. Each call to one of the search methods returns a single page of items. The PerPage property indicates the maximum number of items returned in a single page. Prior to subsequent calls, the caller advances the page by incrementing the value of the Page property. The default value for the Page property is 1, meaning that the first page of items is returned by default. |
Parameters | A dictionary of name/value pairs that are appended to the GitHub API’s URL as query string parameters. In general, the caller should treat this dictionary as read-only. The various properties of derived classes will alter this dictionary indirectly on the caller’s behalf. |
PerPage | The number of items per page. This is the maximum number of items that will be returned by a single call to one of the search methods. The default value for the PerPage property is 100. |
Sort | Sort the search results by the specified field. This read-only property is set indirectly via the SortField property in a derived class. |
Term | Limit the search results to those containing the specified text. This read-only property is set indirectly via the constructor for the request class. |
SearchCode Method
When invoking the SearchCode
method, the following criteria are exposed by the SearchCodeRequest
class. These properties are in addition to those provided by the BaseSearchRequest
class, from which it is derived. Note: Sample code that initializes all of these properties follows the table.
Property | Description |
Extension | Limit search results to code with the specified file extension. |
FileName | Limit search results to code with the specified file name. |
Forks | A value that determines if the search results include code in forked repositories. |
In | Limit the search results to code where the specified fields contain the search term (Term ). |
Language | Limit the search results to code written in the specified programming language. |
Organization | Limit the search results to code for the specified organization. |
Path | Limit the search results to code in the specified file path. |
Repos | Limit the search results to code in the specified set of repositories, using an "owner/name" format for each individual repository. |
Size | Limit the search results to code where the size (in bytes) falls within the specified range. |
SortField | Sort the search results by the specified field. |
User | Limit the search results to the specified user. |
SearchCode (Simple Search)
The following is a simple search request that finds the first 100 files, in the "octokit/octokit.net" repository, which contain the text "issue" in the file path.
SearchCodeResult result = await client.Search.SearchCode(
new SearchCodeRequest("issue")
{
In = new CodeInQualifier[] { CodeInQualifier.Path },
Language = Language.CSharp,
Repos = new RepositoryCollection { "octokit/octokit.net" }
});
SearchCode (All Fields)
The following code sample demonstrates the initialization of a request (SearchCodeRequest
) where all of the properties are set.
int fromNumber = 100;
int toNumber = 1000;
string extension = ".cs";
string fileName = "IssueCommentPayload";
string organization = "octokit";
string path = "Octokit/Models/Response/ActivityPayloads";
string repository = "octokit/octokit.net";
string term = "issue";
string user = "octokit";
var request = new SearchCodeRequest(term)
{
Extension = extension,
FileName = fileName,
Forks = false,
In = new CodeInQualifier[] { CodeInQualifier.Path },
Language = Language.CSharp,
Order = SortDirection.Descending,
Organization = organization,
Path = path,
Repos = new RepositoryCollection { repository },
Size = new Range(fromNumber, toNumber),
SortField = CodeSearchSort.Indexed,
User = user
};
SearchIssues Method
When invoking the SearchIssues
method, the following criteria are exposed by the SearchIssuesRequest
class. These properties are in addition to those provided by the BaseSearchRequest
class, from which it is derived. Note: Sample code that initializes all of these properties follows the table.
Property | Description |
Archived | A value that determines if the search results are limited to issues in only archived or only non-archived repositories. The default is to include both archived and non-archived repositories. |
Assignee | Limit the search results to issues assigned to the specified user. |
Author | Limit the search results to issues created by the specified user. |
Base | Limit the search results to issues based on the branch they are merging into. |
Closed | Limit the search results to issues closed during the specified range of dates. |
Commenter | Limit the search results to issues commented on by the specified user. |
Comments | Limit the search results to issues that have a number of comments within the specified range. |
Created | Limit the search results to issues created during the specified range of dates. |
Exclusions | Limit the search results to exclude the specified criteria. |
| Assignee | Exclude issues assigned to the specified user. |
| Author | Exclude issues created by the specified user. |
| Base | Exclude issues based on the branch they are merging into. |
| Commenter | Exclude issues commented on by the specified user. |
| Head | Exclude issues descended from the specified branch. |
| Involves | Exclude issues assigned to, created by, commented on, or mentioning the specified user. |
| Labels | Exclude issues with the specified labels. |
| Language | Exclude issues that are in repositories that match the specified programming language. |
| Mentions | Exclude issues mentioning the specified user. |
| Milestone | Exclude issues with the specified milestone. |
| State | Exclude issues in the specified state (e.g. open or closed). |
| Status | Exclude issues with the specified commitment status (e.g. pending, success, error, failure, etc.). |
Head | Limit the search results to issues descended from the specified branch. |
In | Limit the search results to issues where the specified fields contain the search term (Term ). |
Involves | Limit the search results to issues assigned to, created by, commented on, or mentioning the specified user. |
Is | Limit the search results to issues that match one or more of the specified states. For example, issues that are open, closed, merged, unmerged, etc. |
Labels | Limit the search results to issues with the specified labels. The labels are specified as a comma-separated list. |
Language | Limit the search results to issues that are in repositories that match the specified programming language. |
Mentions | Limit the search results to issues mentioning the specified user. |
Merged | Limit the search results to issues that were merged within the specified date range. |
Milestone | Limit the search results to issues with the specified milestone. |
No | Limit the search results to issues missing the specified metadata. For example, issues that lack a label, milestone, or assigned user. |
Repos | Limit the search results to issues in the specified set of repositories, using an "owner/name" format for each individual repository. |
SortField | Sort the search results by the specified field. |
State | Limit the search results to issues in the specified state (e.g. open or closed). |
Status | Limit the search results to issues with the specified commitment status (e.g. pending, success, error, failure, etc.). |
Team | Limit the search results to issues mentioning the specified team (within an organization). |
Type | Limit the search results to issues of the specified type (e.g. issues or pull requests). |
Updated | Limit the search results to issues updated during the specified range of dates. |
User | Limit the search results to issues in repositories owned by the specified user. |
SearchIssues (Simple Search)
The following is a simple search request that finds the first 100 issues, for the "octokit/octokit.net" repository, which contain the text "bug" in the title.
SearchIssuesResult result = await client.Search.SearchIssues(
new SearchIssuesRequest("bug")
{
In = new IssueInQualifier[] { IssueInQualifier.Title },
Repos = new RepositoryCollection { "octokit/octokit.net" }
});
The SearchIssues
method does support the ability to search across multiple repositories. However, its usefulness is limited. At this time (2/6/2019), the Repository
property, for the resulting issues, is not populated. As a result, it is not possible to tell to which repository a resulting issue refers.
Until the API provides a remedy, it is recommended that searches are limited to a single repository (as in the example above).
SearchIssues (All Fields)
The following code sample demonstrates the initialization of a request where all of the properties are set. While the search itself is nonsensical, it does provide a valid example of a complex initialization.
var fromDate = new DateTime(2018, 3, 17);
var toDate = new DateTime(2019, 3, 17);
int fromNumber = 1;
int toNumber = 10;
string branch = "master";
string excludedBranch = "other";
string excludedLabel = "wth";
string excludedMilestone = "Nothing Done";
string excludedUser = "somebody";
string label = "up-for-grabs";
string milestone = "API Cleanup";
string repository = "octokit/octokit.net";
string term = "bug";
string user = "octokit";
var request = new SearchIssuesRequest(term)
{
Archived = true,
Assignee = user,
Author = user,
Base = branch,
Closed = new DateRange(fromDate, toDate),
Commenter = user,
Comments = new Range(fromNumber, toNumber),
Created = new DateRange(fromDate, SearchQualifierOperator.GreaterThan),
Exclusions = new SearchIssuesRequestExclusions
{
Assignee = excludedUser,
Author = excludedUser,
Base = excludedBranch,
Commenter = excludedUser,
Head = branch,
Involves = excludedUser,
Labels = new string[] { excludedLabel },
Language = Language.Ada,
Mentions = excludedUser,
Milestone = excludedMilestone,
State = ItemState.Open,
Status = CommitState.Error
},
Head = branch,
In = new IssueInQualifier[] { IssueInQualifier.Title },
Involves = user,
Is = new IssueIsQualifier[] { IssueIsQualifier.Public },
Labels = new string[] { label },
Language = Language.CSharp,
Mentions = user,
Merged = new DateRange(toDate, SearchQualifierOperator.LessThan),
Milestone = milestone,
No = IssueNoMetadataQualifier.Assignee,
Order = SortDirection.Descending,
Repos = new RepositoryCollection() { repository },
SortField = IssueSearchSort.Created,
State = ItemState.Closed,
Status = CommitState.Success,
Type = IssueTypeQualifier.Issue,
Updated = new DateRange(toDate, SearchQualifierOperator.LessThanOrEqualTo),
User = user
};
SearchLabels Method
When invoking the SearchLabels
method, the following criteria are exposed by the SearchLabelsRequest
class. These properties are in addition to those provided by the BaseSearchRequest
class, from which it is derived. Note: Sample code that initializes all of these properties follows the table.
Property | Description |
RepositoryId | Limit the search results to labels in the repository with the specified unique identity. |
SortField | Sort the search results by the specified field. |
SearchLabels (Simple Search)
When compared to the other search methods, the SearchLabels
method is far less friendly and useful, for the following reasons:
- It requires that you have already previously found the unique identity of a repository.
- Almost all of its criteria are required (instead of being optional).
- It offers very limited criteria.
- While available, using the parameterless constructor will result in an invalid request, since a search term is required, but not provided.
The following is a simple search request that finds the first 100 labels, for the "octokit/octokit.net" repository, that start with the text "category".
Repository repository = await client.Repository.Get("octokit", "octokit.net");
SearchLabelsResult result = await client.Search.SearchLabels(
new SearchLabelsRequest("category", repository.Id));
SearchLabels (All Fields)
The following code sample demonstrates the initialization of a request where all of the properties are set.
string term = "category";
Repository repository = await client.Repository.Get("octokit", "octokit.net");
var request = new SearchLabelsRequest(term, repository.Id)
{
Order = SortDirection.Descending,
SortField = LabelSearchSort.Created
};
SearchRepo Method
When invoking the SearchRepo
method, the following criteria are exposed by the SearchRepositoriesRequest
class. These properties are in addition to those provided by the BaseSearchRequest
class, from which it is derived. Note: Sample code that initializes all of these properties follows the table.
Property | Description |
Archived | A value that determines if the search results are limited to only archived or only non-archived repositories. The default is to include both archived and non-archived repositories. |
Created | Limit the search results to repositories created during the specified range of dates. |
Fork | A value that determines if the search results include forked repositories. |
Forks | Limit the search results to repositories where the number of forks falls within the specified range. |
In | Limit the search results to repositories where the specified fields contain the search term (Term ). |
Language | Limit the search results to repositories that match the specified programming language. |
Size | Limit the search results to repositories where the size (in kilobytes) falls within the specified range. |
SortField | Sort the search results by the specified field. |
Stars | Limit the search results to repositories where the number of stars falls within the specified range. |
Updated | Limit the search results to repositories updated during the specified range of dates. |
User | Limit the search results to repositories owned by the specified user. |
SearchRepo (Simple Search)
The following is a simple search request that finds the first 100 repositories that contain the text "octokit" in the repository name.
SearchRepositoryResult result = await client.Search.SearchRepo(
new SearchRepositoriesRequest("octokit")
{
In = new InQualifier[] { InQualifier.Name }
});
SearchRepo (All Fields)
The following code sample demonstrates the initialization of a request where all of the properties are set.
var fromDate = new DateTime(2012, 3, 17);
var toDate = new DateTime(2019, 3, 17);
int fromNumber = 1;
int toNumber = 10000;
string term = "octokit";
string user = "octokit";
var request = new SearchRepositoriesRequest(term)
{
Archived = false,
Created = new DateRange(fromDate, toDate),
Fork = ForkQualifier.IncludeForks,
Forks = new Range(fromNumber, toNumber),
In = new InQualifier[] { InQualifier.Name },
Language = Language.CSharp,
Order = SortDirection.Descending,
Size = new Range(fromNumber, SearchQualifierOperator.GreaterThan),
SortField = RepoSearchSort.Stars,
Stars = new Range(fromNumber, SearchQualifierOperator.GreaterThanOrEqualTo),
Updated = new DateRange(fromDate, SearchQualifierOperator.GreaterThan),
User = user
};
SearchUsers Method
When invoking the SearchUser
method, the following criteria are exposed by the SearchUsersRequest
class. These properties are in addition to those provided by the BaseSearchRequest
class, from which it is derived. Note: Sample code that initializes all of these properties follows the table.
Property | Description |
AccountType | Limit the search results to users with the specified type of account (e.g. personal or organization). |
Created | Limit the search results to users created during the specified range of dates. |
Followers | Limit the search results to users with the specified number of followers. |
In | Limit the search results to users where the specified fields contain the search term (Term ). |
Language | Limit the search results to users who own repositories with the specified programming language. |
Location | Limit the search results to users in the specified location. |
Repositories | Limit the search results to users who own a number of repositories that falls within the specified range. |
SortField | Sort the search results by the specified field. |
SearchUsers (Simple Search)
The following is a simple search request that finds the first 100 users (of account type User
) that contain the text "oct" in one of the default fields (user’s login name, full name, or e-mail address).
SearchUsersResult result = await client.Search.SearchUsers(
new SearchUsersRequest("oct")
{
AccountType = AccountSearchType.User
});
Note: By specifying an account type of Org
, a similar search could be conducted for organizations instead of personal users.
SearchUsers (All Fields)
The following code sample demonstrates the initialization of a request where all of the properties are set.
var fromDate = new DateTime(2001, 3, 17);
int fromNumber = 1;
int toNumber = 1000;
string location = "Ontario";
var request = new SearchUsersRequest("code")
{
AccountType = AccountSearchType.User,
Created = new DateRange(fromDate, SearchQualifierOperator.GreaterThan),
Followers = new Range(fromNumber, SearchQualifierOperator.GreaterThanOrEqualTo),
In = new UserInQualifier[] { UserInQualifier.Username },
Language = Language.CSharp,
Location = location,
Order = SortDirection.Descending,
Repositories = new Range(fromNumber, toNumber),
SortField = UsersSearchSort.Followers
};
User Property
To access a user directly, without first searching for it, use the Get
method as follows:
User user = await client.User.Get("octokit");
This same method gets users with both personal and organization account types.
GitHub API Demo Application
A simple Windows Form application is included, with this article, to demonstrate searches using the Octokit.net framework. This application is purely intended to demonstrate searching and provide some code samples. It is not intended as a production application and has not been tested for that purpose.
When the application is first started, you will be prompted for GitHub credentials. The login screen supports three types of authentication: Unauthenticated Access, Basic Authentication, and OAuth Token Authentication.
To conduct a search, click "Edit…Find…" and select the item for which you want to search.
Fill in the criteria for your search and click OK. Below, we search for a repository with the text "octokit".
The results will be displayed in a data grid like the following:
By default, only minimal information is displayed. It is possible to change the columns of information that are displayed and their order. To do this, click "Edit…Select Columns…"…
A dialog will appear that allows you to select and order the columns:
Additionally, by double-clicking on any item in the data grid, it is possible to see additional detail in the "Detail" tab…
The application contains a number of other features with which the user can play. From a GitHub perspective, the application is read-only. So, it is comparatively safe to use.
The majority of the code deals with user interaction. Within the code, the GitHub API usage is limited to the Searcher
class and the classes derived from it: CodeSearcher
, IssueSearcher
, LabelSearcher
, RepositorySearcher
, and UserSearcher
.
GitHub API Snippets Application
A simple Windows Console application is also provided. In general, most of the code samples in this article came from the Program
class in this application. The user interface for the application is intentionally primitive to avoid distracting from the GitHub API samples.
A sample session is shown below.
Further Reading
For further reading, on this topic, the following links provide invaluable information: