Ghee
This is an unofficial ruby client for the GitHub API. The end goal is a complete, simple, and intuitive ruby API for all things Github.
Usage
Instantiate the client with basic auth:
gh = Ghee.basic_auth("rauhryan","password")
Instantiate the client with auth token:
gh = Ghee.access_token("1234oijgakjioewj1o4oij")
Create an OAuth access token:
user_name, password, scopes = "rauhryan", "secret", ["user","repo"]
token = Ghee.create_token(user_name, password, scopes)
Create a client for github enterprise
gh = Ghee.access_token("your_token","https://foo.com")
gh = Ghee.basic_auth("your_user", "your_pass", "https://foo.com")
Gists
Usage
List a user's gists:
gh.user('jonmagic').gists
List authenticated users gists:
gh.gists
List all public gists:
gh.gists.public
List the authenticated user's starred gists:
gh.gists.starred
Get a single gist:
gist_id = "1393990"
gh.gists(gist_id)
Create a gist (see docs for all possible params):
gh.gists.create({
:description => 'Ghee'
:public => true,
:files => {
'file1.txt' => {
:content => 'buttah yo bread'
}
}
})
Edit a gist:
gh.gists("1393990").patch({
:files => {
'gistfile1.md' => {
:content => 'clarified I say'
}
}
})
Star a gist:
gh.gists("1393990").star
Unstar a gist:
gh.gists("1393990").unstar
Check if a gist is starred:
gh.gists("1393990").starred?
Delete a gist:
gh.gists("1393990").destroy
Comments
List comments for a gist:
gh.gists("1382919").comments
Get a single gist comment:
gh.gists.comments("1231414")
Create a single gist comment:
gh.gists.comments("1231414").create({
:body => "new body"
})
Patch a single gist comment:
gh.gists.comments("1231414").patch({
:body => "new body"
})
Delete a comment for a gist:
gh.gists.comments("1231441").destroy
Repos
Get a single repo:
gh.repos("rauhryan", "ghee")
Pulls
List pull requests on a repo (see List pull requests )
gh.repos("rauhryan", "ghee").pulls
gh.repos("rauhryan", "ghee").pulls({
:state => "closed" # optional
})
Get a single pull request on a repo (see Get a single pull request )
gh.repos("rauhryan", "ghee").pulls(1097)
Create a pull request (see Create a pull request )
gh.repos("rauhryan", "ghee").pulls.create({
:title=>"take my awesome code!",
:body=>"This code is so awesome. Let me tell you why...",
:base=>"master",
:head=>"octocat:awesomebranch"
})
Update a pull request (see Update a pull request )
gh.repos("rauhryan", "ghee").pulls(1097).patch({:title=>"New title", :body=>"New body", :state=>"closed"})
List commits on a pull request (see List commits a pull request )
gh.repos("rauhryan", "ghee").pulls(1097).commits
List files on a pull request (see List files a pull request )
gh.repos("rauhryan", "ghee").pulls(1097).files
Get if a pull request has been merged (see Get if a pull request has been merged )
gh.repos("rauhryan", "ghee").pulls(1097).merged? #=> true
Merge a pull request (see Merge a pull request )
gh.repos("rauhryan", "ghee").pulls(1097).merge!
gh.repos("rauhryan", "ghee").pulls(1097).merge!("It's like hitting the Merge Button(TM)")
Commits
List commits on a repo:
gh.repos("rauhryan", "ghee").commits
gh.repos("rauhryan", "ghee").commits({
:sha => "awesome_branch" # optional
})
gh.repos("rauhryan", "ghee").commits( {
:path => "/path/to/file" # only commits containing this path
})
Get a single commit:
gh.repos("rauhryan", "ghee").commits("sha")
List commit comments for a repo:
gh.repos("rauhryan", "ghee").comments
List comments for a single commit:
gh.repos("rauhryan", "ghee").commits("sha").comments
Create a commit comment:
gh.repos("rauhryan", "ghee").commits("sha").comments.create({
:body => "sweet codez yo!", #required
:commit_id => "sha", #required
:line => 123, #required
:path => "/path/to/file", #required
:position => 4 #required
})
Get a single commit comment:
gh.repos("rauhryan", "ghee").comments(123)
Update a commit comment:
gh.repos("rauhryan", "ghee").comments(123).patch(:body => "new text")
Destroy a commit comment:
gh.repos("rauhryan", "ghee").comments(123).destroy
Compare two commits:
gh.repos("rauhryan", "ghee").compare("basesha","headsha")
Collaborators
List a repos collaborators:
gh.repos("rauhryan", "ghee").collaborators
Get a single collaborator:
gh.repos("rauhryan", "ghee").collaborators("herp") # => false
gh.repos("rauhryan", "ghee").collaborators("jonmagic") # => true
Add a collaborator:
gh.repos("rauhryan", "ghee").collaborators.add("herp") # => true
Remove a collaborator:
gh.repos("rauhryan", "ghee").collaborators.remove("herp") # => true
Forks
List the hooks for a repo:
gh.repos("rauhryan", "ghee").forks
gh.repos("rauhryan", "ghee").forks(:sort => "newest") # => `newest`, `oldest`, `watchers`
Create a fork:
gh.repos("rauhryan", "ghee").forks.create # => forks the repo to the authenticated user
Keys
List the keys for a repo:
gh.repos("rauhryan", "ghee").keys
Get a single key for a repo:
gh.repos("rauhryan", "ghee").keys(123)
Create a key for a repo:
gh.repos("rauhryan", "ghee").keys.create({
:title => "customer deploy key",
:key => "ssh-rsa AAA ..."
})
Update a key for a repo:
gh.repos("rauhryan", "ghee").keys.patch({
:title => "customer deploy key",
:key => "ssh-rsa AAA ..."
})
Destroy a key for a repo:
gh.repos("rauhryan", "ghee").keys(123).destroy # => true
Hooks
Get the hooks for a repo:
gh.repos("rauhryan", "ghee").hooks
Get a single hook for a repo:
gh.repos("rauhryan", "ghee").hooks(12)
Create a hook for a repo: (see docs for all possible params):
gh.repos("rauhryan", "ghee").hooks.create({
:name => "web",
:config => {:url => "http://huboard.com/webhook"}
})
Update a hook for a repo: (see docs for all possible params):
gh.repos("rauhryan", "ghee").hooks(12).patch({
:name => "web",
:config => {:url => "http://huboard.com/webhook"}
})
Destroy a hook for a repo:
gh.repos("rauhryan", "ghee").hooks(1).destory
Downloads
Get the downloads for a repo:
gh.repos("rauhryan", "ghee").downloads
Get a single download for a repo:
gh.repos("rauhryan", "ghee").downloads(12)
Create a download for a repo:
gh.repos("rauhryan", "ghee").downloads.create("/path/to/file","description")
Destroy a download for a repo:
gh.repos("rauhryan", "ghee").downloads(12).destroy
Watchers
List watchers for a repo:
gh.repos("rauhryan", "ghee").watchers
List repos being watched:
gh.user.watched
gh.users("jonmagic").watched
Check if you are watching a repo:
gh.user.watching? "rauhryan", "huboard"
Watch a repo:
gh.user.watch "rauhryan", "huboard"
Unwatch a repo:
gh.user.watch! "rauhryan", "huboard"
Milestones
Get the milestones for a repo:
gh.repos("rauhryan", "ghee").milestones
Get a single milestone for a repo:
gh.repos("rauhryan", "ghee").milestones(12)
Create a milestone for a repo: (see docs for all possible params):
gh.repos("rauhryan", "ghee").milestones.create({
:title => "Remove the suck!",
:description => "I found this suck, remove it please"
})
Update a milestone for a repo: (see docs for all possible params):
gh.repos("rauhryan", "ghee").milestones(12).patch({
:description => "I found this suck, remove it please"
})
Destroy a milestone for a repo:
gh.repos("rauhryan", "ghee").milestones(1).destory
Issues
Get the issues for a repo:
gh.repos("rauhryan", "ghee").issues
Get a single issue for a repo:
gh.repos("rauhryan", "ghee").issues(12)
Create an issue for a repo: (see docs for all possible params):
gh.repos("rauhryan", "ghee").issues.create({
:title => "Remove the suck!",
:body => "I found this suck, remove it please"
})
Update an issue for a repo: (see docs for all possible params):
gh.repos("rauhryan", "ghee").issues(12).patch({
:body => "I found this suck, remove it please"
})
Close an issue for a repo:
gh.repos("rauhryan", "ghee").issues(12).close
Get the closed issues for a repo:
gh.repos("rauhryan", "ghee").issues(12).closed
Comments
Get the comments for an issue:
gh.repos("rauhryan", "ghee").issues(12).comments
Get a single comment for an issue
gh.repos("rauhryan", "ghee").issues.comments(482910)
Create a comment for an issue:
gh.repos("rauhryan", "ghee").issues(12).comments.create({:body => "hey i'll help fix that suck"})
Update a single comment for an issue
gh.repos("rauhryan", "ghee").issues.comments(482910).patch({:body =>
"nevermind I can't figure it out"})
Destroy a comment for an issue
gh.repos("rauhryan", "ghee").issues.comments(482910).destroy
Orgs
Usage
Get a list of orgs for the current user:
gh.orgs
Get a specific org:
gh.orgs("huboard")
Patch an organization:(see docs for all possible params):
gh.orgs("huboard").patch({ :company => "awesome company" })
Repos
Get a list of repos for an org:
gh.orgs("huboard").repos
Notes: see above for all the available api methods for repos
Teams
Get a list of teams for an org:
gh.orgs("huboard").teams
Get a single team for an org:
gh.orgs("huboard").teams(110234)
Create team for an org:
gh.orgs("huboard").teams.create :name => "awesome_developers"
Patch a team for an org:
gh.orgs("huboard").teams(110234).patch :name => "junior_developers"
Delete a team for an org:
gh.orgs("huboard").teams(110234).delete
Members
Get a list of members for a team:
gh.orgs("huboard").teams(110234).members
Add a member to a team:
gh.orgs("huboard").teams(110234).members.add("rauhryan")
Remove a member from a team:
gh.orgs("huboard").teams(110234).members.remove("rauhryan")
Teams
Usage
Get a single team:
gh.team(110234)
Create a team:
gh.team.create :name => "awesome_developers"
Patch a team:
gh.team(110234).patch :name => "junior_developers"
Delete a team:
gh.team(110234).delete
Members
Get a list of members for a team:
gh.team(110234).members
Add a member to a team:
gh.team(110234).members.add("rauhryan")
Remove a member from a team:
gh.team(110234).members.remove("rauhryan")
Users
Usage
Get a single user:
gh.users('jonmagic')
Get the authenticated user:
gh.user
Update authenticated user (see docs for all possible params):
gh.user.patch({
:name => 'Jon Hoyt',
:email => '[email protected]',
# …etc
})
Keys
List the keys for a user:
gh.user.keys
Get a single key for a user:
gh.user.keys(123)
Create a key for a user:
gh.user.keys.create({
:title => "customer deploy key",
:key => "ssh-rsa AAA ..."
})
Update a key for a user:
gh.user.keys.patch({
:title => "customer deploy key",
:key => "ssh-rsa AAA ..."
})
Destroy a key for a user:
gh.user.keys(123).destroy # => true
Repos
Get a list of repos for the current user:
gh.user.repos
Get a list of repos for a specific user:
gh.users("rauhryan").repos
Get a single repos for the current user:
gh.user.repos("ghee")
Get a single repos for a specific user:
gh.users("rauhryan").repos("ghee")
Notes: see above for all the available api methods for repos
Get a list of orgs for the current user:
gh.user.orgs
Get a list of orgs for a specific user:
gh.users("rauhryan").orgs
Notes: see above for all the available api methods for orgs
Followers
Get the followers for a user:
gh.user.followers
gh.users("rauhryan").followers
Get users following another user:
gh.users("rauhryan").following
gh.user.following
Check if you are following a user:
gh.user.following? "rauhryan"
Follow a user:
gh.user.follow "rauhryan"
Unfollow a user:
gh.user.follow! "rauhryan"
Git Data
Blobs
Get a blob:
gh.repos("rauhryan","huboard").git.blobs("sha")
Create a blob:
gh.repos("rauhryan","huboard").git.blobs.create({
:content => "Contents of blob",
:encoding => "utf-8"
})
Commit
Get a commit:
gh.repos("rauhryan","huboard").git.commits("sha")
Create a commit:
gh.repos("rauhryan","huboard").git.commits.create({
:message => "message of commit",
:tree => "sha",
:parents => ["sha","sha"]
})
References
Get a reference:
gh.repos("rauhryan","huboard").git.refs("heads/master")
Get all references:
gh.repos("rauhryan","huboard").git.refs
gh.repos("rauhryan","huboard").git.refs("tags")
gh.repos("rauhryan","huboard").git.refs("heads")
Create a reference:
gh.repos("rauhryan","huboard").git.refs.create({
:ref => "refs/heads/master",
:sha => "287efc2351325e215j235f25215el1"
})
Update a reference:
gh.repos("rauhryan","huboard").git.refs("heads/master").patch({
:sha => "287efc2351325e215j235f25215el1",
:force => true
})
Delete a reference:
gh.repos("rauhryan","huboard").git.refs("tags/v1.0").destroy
Tags
Get a tag:
gh.repos("rauhryan","huboard").git.tags("sha")
Create a tag:
gh.repos("rauhryan","huboard").git.tags.create({
:tag => "v1.0",
:message => "tag message",
:object => "sha", #sha of the object you are tagging, usually a commit
:type => "commit", #the type of object you are tagging
:tagger => {
:name => "Ryan Rauh",
:email => "[email protected]",
:date => "2011-06-17T14:53:35-07:00"
}
})
Trees
Get a tree:
gh.repos("rauhryan","huboard").git.trees("sha")
Get a tree recursively:
gh.repos("rauhryan","huboard").git.trees("sha",{:recursive => 1})
Create a tree:
gh.repos("rauhryan","huboard").git.trees.create({
:base_tree => "sha", #optional
:tree => [
{
:path => "/path/to/thing",
:mode => 100644,
:type => "blob",
:sha => "sha"
# :content => "" # can use this instead of sha
}
]
})
Events
Usage
List public events:
gh.events
Pagination
Usage
Ghee fully supports pagination for anything that returns a list, for example repo issues.
gh.repos("rauhryan","huboard").issues.paginate(:per_page => 30, :page => 1) #=> returns first page of issues
gh.repos("rauhryan","huboard").issues.paginate(:per_page => 30, :page => 2) #=> returns page two of issues
gh.repos("rauhryan","huboard").issues.paginate(:per_page => 30, :page => 2).first_page #=> 1
gh.repos("rauhryan","huboard").issues.paginate(:per_page => 30, :page => 2).last_page #=> 4
gh.repos("rauhryan","huboard").issues.paginate(:per_page => 30, :page => 2).next_page #=> 3
gh.repos("rauhryan","huboard").issues.paginate(:per_page => 30, :page => 2).prev_page #=> 1
Ghee also provides a convienence method for all the pages
gh.repos("rauhryan","huboard").issues.all #=> return all the pages
Filtering parameters
Usage
Many of the api calls allow you to pass in additional paramters to filter and sort your data, for example issues provide
- filter
assigned
mentioned
subscribed
created
- state
open
closed
default
- labels
- list of labels comma delimited
herp,derp
- list of labels comma delimited
- direction
asc
ordesc
These can all be passed into ghee through an options hash:
gh.repos("rauhryan", "huboard").issues(:state => "closed", :sort => "desc")
Note you can also change parameters with pagination!
gh.repos("rauhryan", "huboard").issues(:state => "closed").all
Testing
The test suite uses VCR to cache actual requests to the Github API in a directory called responses in the spec directory.
In order for VCR to make and cache the actual calls to the Github API you will need to copy spec/settings.yml.sample to spec/settings.yml and configure it with your GitHub username, either a GitHub access token or your GitHub password, a test repo for it to hit against (which you should setup ahead of time), and finally an organization you belong to (for the entire suite of tests to pass you have to belong to an org).
This file is ignored by git (see .gitignore) so you can commit any changes you make to the gem without having to worry about your user/token/pass/org being released into the wild.
Before you run the api test suite:
Fork [Ghee-Test](https://github.com/rauhryan/ghee_test)
Set the settings.yml repo key to ghee_test
On ghee_test:
- Enable issue tracking on (your username)/ghee
- Create a Public Gist and Star it
- Create an issue with the title "Seeded"
- Create a comment on a commit line
Now run the test suite:
bundle
bundle exec rake api
CONTRIBUTE
If you'd like to hack on Ghee, start by forking the repo on GitHub:
https://github.com/rauhryan/ghee
The best way to get your changes merged back into core is as follows:
- Clone down your fork
- Create a thoughtfully named topic branch to contain your change
- Hack away
- Add tests and make sure everything still passes by running
bundle exec rake
- If you are adding new functionality, document it in the README
- Do not change the version number, we will do that on our end
- If necessary, rebase your commits into logical chunks, without errors
- Push the branch up to GitHub
- Send a pull request for your branch