Skip to content

Instantly share code, notes, and snippets.

@Maks3w
Last active December 19, 2015 07:59
Show Gist options
  • Save Maks3w/5922377 to your computer and use it in GitHub Desktop.
Save Maks3w/5922377 to your computer and use it in GitHub Desktop.
GitHub Git Flow Killer first stub
<!DOCTYPE html>
<html>
<head>
<title>Merge GitHub's PRs with Git Flow style</title>
<link rel="stylesheet" href="css/bootstrap.css"/>
<link rel="stylesheet" href="css/bootstrap-responsive.min.css"/>
</head>
<body>
<div class="container">
<form class="form-inline">
GitHub token is saved in the browser's localStorage
<h2 class="form-signin-heading">Select a repository</h2>
<!--
<label>GitHub Token
<input type="text" name="github_token" id="github_token"/>
</label>
-->
<label>Organization
<select name="organizations" id="organizations" disabled>
<option>You must provide a valid Token first</option>
</select>
</label>
<label>Repository
<select name="repositories" id="repositories" disabled>
<option>You must select a organization first</option>
</select>
</label>
<h2>DON'T USE THIS IN PRODUCTION YET</h2>
<ul id="pull-request"></ul>
</form>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<script>
var API_URL = 'https://api.github.com';
/**
* GitHub API call from https://github.com/michael/github
*
* @param method HTTP method.
* @param url Endpoint URI.
* @param data Parameters.
* @param cb Response callback(json|raw).
* @private
*/
function _request(method, url, data, cb) {
function getURL() {
return url + ((/\?/).test(url) ? "&" : "?") + (new Date()).getTime();
}
var xhr = new XMLHttpRequest();
xhr.dataType = 'json';
xhr.open(method, getURL());
xhr.onreadystatechange = function () {
if (this.readyState == 4) {
if (this.status >= 200 && this.status < 300 || this.status === 304) {
cb(this.responseText ? JSON.parse(this.responseText) : true);
} else {
err(this);
}
}
};
xhr.setRequestHeader('Accept', 'application/vnd.github.raw');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Authorization', 'token ' + localStorage.githubToken);
data ? xhr.send(JSON.stringify(data)) : xhr.send();
}
/**
* API error handle
*
* @param {XMLHttpRequest} request
*/
function err(request) {
$('#pull-request').html(request.response);
}
function fillOrganizations() {
_request('GET', API_URL + '/user/orgs', null, function (orgs) {
var organizations = $('#organizations');
organizations.html($('<option />').text('Choose the organization of the repository'));
organizations.append($('<option />').val('me').text('me'));
$.each(orgs, function (k, org) {
organizations.append($('<option />').val(org.repos_url).text(org.login));
});
organizations.removeAttr('disabled');
organizations.change(function () {
var repoUrl = organizations.val();
if ('me' == repoUrl) {
repoUrl = API_URL + '/user/repos';
}
_request('GET', repoUrl + '?type=all&per_page=100', null, fillRepositories);
});
});
}
function fillRepositories(repos) {
var repositories = $('#repositories');
repositories.html($('<option />').text('Choose the repository'));
$.each(repos, function (k, repo) {
if (repo.permissions.pull) {
repositories.append($('<option />').val(repo.full_name).text(repo.name));
}
});
repositories.removeAttr('disabled');
repositories.change(function () {
showPRs(repositories.val());
});
}
function showPRs(repoFullName) {
_request('GET', API_URL + '/repos/' + repoFullName + '/pulls', null, function (prs) {
var list = $('#pull-request');
list.html('');
$.each(prs, function (k, pr) {
list.append($('<li />')
.append($('<a />')
.attr('href', pr.html_url)
.text(pr.number + ' - ' + pr.title)
)
.append($('<input />')
.attr('type', 'button')
.attr('class', 'btn btn-danger')
.val('Merge')
.click([repoFullName, pr.number], function (e) {
gitFlowMerge(e.data[0], e.data[1]);
})
)
)
});
});
}
function gitFlowMerge(repoFullName, prNumber) {
function _createBranch(repoFullName, branchName, branchSource, cb) {
_request('GET', API_URL + '/repos/' + repoFullName + '/git/refs/heads/' + branchSource, null, function (data) {
var args = {
"ref": 'refs/heads/' + branchName,
"sha": data.object.sha
};
_request('POST', API_URL + '/repos/' + repoFullName + '/git/refs', args, function (data) {
cb(data.ref);
});
});
}
function _deleteBranch(repoFullName, branchName, cb) {
_request('DELETE', API_URL + '/repos/' + repoFullName + '/git/refs/heads/' + branchName, null, cb);
}
function _mergeBranch(pr, head, base, commit, cb) {
var args = {
"base" : base,
"head" : head,
"commit_message": commit
};
_request('POST', pr.base.repo.merges_url, args, cb);
}
_request('GET', API_URL + '/repos/' + repoFullName + '/pulls/' + prNumber, null, function (pr) {
if (pr.merged || !pr.mergeable) {
return;
}
var branchName = 'pr_' + prNumber;
_createBranch(repoFullName, branchName, 'master', function (reference) {
_mergeBranch(pr, pr.merge_commit_sha, branchName, "Merge PR(#" + prNumber + ")", function () {
_mergeBranch(pr, branchName, 'master', "Merge PR(#" + prNumber + ") / master", function () {
_mergeBranch(pr, branchName, 'develop', "Merge PR(#" + prNumber + ") / develop", function () {
_deleteBranch(repoFullName, branchName, function () {
alert('merged');
});
});
});
});
});
});
}
$(function () {
if (!localStorage.githubToken) {
var token = prompt('GitHub Token');
if (!token) {
alert('A GitHub token is mandatory for use this tool. Get one in your profile a try again.');
return;
}
localStorage.githubToken = token;
}
fillOrganizations();
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment