This is a Java adapter to the GitHub RESTful API. There are a few other similar implementations on the market, but jcabi-github has a very strong focus on object-oriented principles of programming. On top of that, we have a unique implementation of GitHub server-side functionality, which you can use in your unit tests, eliminating the necessity to connect to GitHub during unit/integration testing. Please, read the blog post Object-Oriented GitHub API by Yegor Bugayenko, the creator of this library.
Java 8 or higher is required.
More details are here: github.jcabi.com.
You may also get help in this Telegram chat.
The set of classes in the
com.jcabi.github
package is the object-oriented API. Use it like this:
By default, the library works with GitHub RESTful API:
import com.jcabi.github.*;
public class Main {
public static void main(String[] args) throws IOException {
GitHub github = new RtGitHub(".. your OAuth token ..");
Repo repo = github.repos().get(
new Coordinates.Simple("octocat/Hello-World")
);
final Issue issue = repo.issues().create("Test title", "Test description");
issue.comments().post("My first comment!");
}
}If you want to work with GitHub's API through another domain,
you can use the URI-constructors
of class RtGitHub. For instance, if you have your own instance
of GitHub deployed under the
domain https://github.mydomain.com, do the following:
final GitHub github = new RtGitHub(URI.create("https://github.mydomain.com"));
//OR
final GitHub github = new RtGitHub(
"<<oauth2_token>>",
URI.create("https://github.mydomain.com")
);
//OR
final GitHub github = new RtGitHub(
"username", "password",
URI.create("https://github.mydomain.com")
);DO NOT change or mask your URIs! Using GitHub under a different domain is fine but do not change the URI paths. Changing the requests' paths is not possible since the whole architecture of this library relies on GitHub's URI paths.
For more complex configurations, you can instantiate
RtGitHub with your own custom Request,
by using the RtGitHub(Request) constructor.
Be sure to configure the Request properly.
See how the default Request
is created -- you basically have to do the same thing.
We also provide MkGitHub, a mock version of the GitHub server, which you can use in your unit tests, for example:
import com.jcabi.github.*;
public class FooTest {
public void submitsCommentToGitHubIssue() {
final Repo repo = new MkGitHub().repos().create(
Json.createObjectBuilder().add("name", "test").build()
);
final Issue issue = repo.issues().create("how are you?", "");
new Foo(issue).doSomething(); // should post a message to the issue
MasterAssert.assertThat(
issue.comments().iterate(),
Matchers.iterableWithSize(1)
);
}
}The library maps every GitHub API concept to a Java interface
(GitHub, Repo, Issue, Comment, etc.) with two
complete parallel implementations: Rt* classes talk to
the live GitHub REST API,
while Mk* classes provide an in-memory mock server.
Unlike github-api,
which ships only a real HTTP implementation,
jcabi-github delivers both under the same interface
hierarchy, so test code and production code share the same API.
New programmers should use RtGitHub in production and
MkGitHub in tests — no mocking framework is needed.
Each interface contains a static inner class Smart
(e.g., Issue.Smart, Comment.Smart) that wraps the
core interface and exposes convenience methods such as
isOpen(), author(), and close().
The base interface holds only identity accessors and
JSON I/O methods,
following the
decorator pattern
as advocated by
Elegant Objects.
New programmers should reach for Issue.Smart rather than
raw Issue when reading human-friendly properties.
Every domain object implements JsonReadable (one json()
method) and JsonPatchable (one patch() method).
There is no ORM or intermediate object mapping: the
JSON document from
the REST endpoint is the canonical state, with typed
extraction handled by SmartJson.
Unlike Jackson-based
libraries that map JSON to POJOs eagerly, each json()
call here is a live HTTP round trip.
New programmers must not assume property reads are cheap;
wrap collections in Bulk<T> to avoid N+1 requests.
RtPagination<T> lazily follows
Link headers
(rel="next") to traverse GitHub's paginated responses.
Without Bulk<T>, each item triggers a separate HTTP call
when its properties are first read.
Bulk<T> pre-injects JSON from the listing response into
each item, collapsing those N+1 requests into the minimum
number of page fetches.
New programmers must wrap iterate() results in
new Bulk<>(...) when iterating large collections.
HTTP cross-cutting concerns — rate-limiting, retries, and
redirects — are composed by stacking Wire decorators
from jcabi-http on the entry
Request via .through().
CarefulWire reads X-RateLimit-Remaining and sleeps
until X-RateLimit-Reset to stay within GitHub's quota
rather than failing with HTTP 429.
Unlike interceptor-based clients such as
OkHttp or
Apache HttpClient,
each behavior here is a standalone immutable class.
New programmers should implement Wire and call .through()
to add custom HTTP behavior.
The Mk* mock stores all state in a single
XML document inside MkStorage,
mutated via Xembly
directives and queried with
XPath.
Unlike HTTP-replay tools such as
WireMock or
MockServer, state is shared
and consistent across the entire object graph: an issue
created via MkIssues is immediately visible via MkRepo.
New programmers can rely on cross-object consistency inside
one MkGitHub instance but must not expect the mock to
validate payloads against the live GitHub API schema.
All classes carry the @Immutable annotation from
jcabi-aspects, enforced by
AspectJ at Maven build time.
No class has setters or mutable fields; the build fails
if any are added.
This contrasts with builder-style libraries such as
github-api that
rely on mutable state.
New programmers must construct new objects rather than
modifying existing ones.
Fork the repository, make changes, submit a pull request.
We promise to review your changes same day and apply to
the master branch, if they look correct.
Please run Maven (3.1 or higher!) build before submitting a pull request:
mvn clean install -PquliceThere are many integration tests that check our classes against live GitHub accounts. In order to run them, you should create a new GitHub OAuth access tokens (how?), and provide them in command line, like this:
mvn clean install -Dit.test=RtGistITCase -Dfailsafe.github.key=<token> \
-Dfailsafe.github.key.second=<second-token> -Dfailsafe.github.repo=<repo>Replace <token> and <second-token> with the OAuth access tokens
of two different GitHub
accounts. This test case will try to fork a gist from first account
into second. Replace
<repo> with the name of repository you create in your first account
(for test purposes only), for example yegor256/test.
OAuth access tokens should have permissions in their
respective repos to all scopes needed by the integration test
suite you want to run
(including delete_repo, which is not set by default!).
Please note that different integration tests may need keys with permissions to different scopes. To run all integration tests, the key should have the following OAuth scopes:
read:orgrepodelete_repoadmin:public_keygistadmin:repo_hookuseruser:email
RtForksITCase requires additional
parameter -Dfailsafe.github.organization=<organization>
where <organization> is an organization name to fork test github repository.
In order to run static analysis checks only use this:
mvn clean install -DskipTests -Dinvoker.skip=true -Pqulice