Recently I had the opportunity to work with GitHub’s API again. This time I was particularily interested in the Repo
Contents API. The goal was to be able to publish files from disk or
embedded resource (read: stream) directly to a GitHub repo without having to clone the repo somewhere and then issue a
git push
.
The API seemed (as is always with case with the GitHub API) straightforward and had methods for creating and updating files. So I got to work…
TL;DR - show me the code/installation instructions
In my particular case, I was trying to pull embedded resources out of an assembly, push them to GitHub and then trigger our CI server to run a build and if successful, trigger a deployment.
To get started, I had to think of what would be ideal for me. I came to the conclusion that I needed:
The goal being code that looked like this:
// get the api token from sonewhere... | |
var service = new ContentService(token); | |
var file = new DiskFile("Files/content_file.gif"); | |
var target = new FileTarget(owner, repo, file.Name); | |
service.PushFile(file, target, "pushing file via GitHubPushLib"); |
I needed to make sure that the app could both create and update a file, so I ended up with the following code:
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
namespace GitHubPushLib | |
{ | |
public sealed class ContentService | |
{ | |
private ContentRepo _repo; | |
private string _authToken; | |
public ContentService(string authToken) | |
: this(authToken, new GitHubContentRepo()) | |
{ | |
} | |
public ContentService(string authToken, ContentRepo repo = null) | |
{ | |
Guard.AgainstNullOrEmpty("authToken", authToken); | |
this._repo = repo; | |
this._authToken = authToken; | |
} | |
public File PushFile(File file, FileTarget target, string message) | |
{ | |
Guard.AgainstNull("file", file); | |
Guard.AgainstNull("target", target); | |
Guard.AgainstNullOrEmpty("message", message); | |
var existingFile = this._repo.GetFile(this._authToken, target); | |
if (existingFile != null) | |
{ | |
// set the hash to the existing one... | |
file.SHA = existingFile.SHA; | |
} | |
return existingFile == null ? | |
this._repo.CreateFile(this._authToken, file, target, message) : | |
this._repo.UpdateFile(this._authToken, file, target, message); | |
} | |
} | |
} |
After only a few hours I had a fully tested implementation that I was able to use. I figured that other people might have the same need, so I packaged it up as a NuGet package.
Install-Package GitHubPushLib
If you’re interested, check out the code on GitHub. I’ve setup Travis CI and would love to see some pull requests!
The repo contains a sample app (with instructions) you can use to play around with.