Skip to content

Instantly share code, notes, and snippets.

@pedropalhari
Last active January 11, 2021 23:20
Show Gist options
  • Save pedropalhari/94bd7b71bc48d4164d5a92612ed9c367 to your computer and use it in GitHub Desktop.
Save pedropalhari/94bd7b71bc48d4164d5a92612ed9c367 to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name [GITHUB] Create branch from issue
// @namespace http://tampermonkey.net/
// @version 1.0
// @description Creates a branch using the issue. Adds a button to the interface.
// @author Pedro Palhari
// @match https://github.com/*/*/issues/*
// @grant none
// ==/UserScript==
const MASTER_BRANCH = "master";
(function () {
"use strict";
/**
* Gets auth token for creating branches
*/
async function getAuthToken() {
let repoUrl = window.location.href.split("/issues")[0];
let response = await fetch(
`${repoUrl}/refs/main?source_action=disambiguate&source_controller=files`,
{
headers: {
accept: "text/html",
"accept-language": "pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7",
"if-none-match": 'W/"114ebe5bc2948d0bb8467ed17e5b9a13"',
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
"x-requested-with": "XMLHttpRequest",
},
referrer: `${repoUrl}`,
referrerPolicy: "no-referrer-when-downgrade",
body: null,
method: "GET",
mode: "cors",
credentials: "include",
}
);
let responseHtml = await response.text();
let authToken = responseHtml
.split('name="authenticity_token" value="')[1] //gets between this
.split('" />')[0]; //and this
return authToken;
}
/**
* Formats the current title into an issue name
*
* @param title Title of the issue
*/
function formatTitle(title) {
return title
.split("\n") //
.map((x) => x.trim()) // Make it only "" and "Text" and "<issue_number>"
.filter((x, index) => x != "" && index < 5) // Crop it to be, at most, 5 words (for branch not become too long names)
.join(" ") //
.replaceAll(" ", "-") //
.toLocaleLowerCase(); // Join them and make "Something beautiful #5" be "something-beautiful-#5"
}
async function createBranchFromIssue() {
let repoUrl = window.location.href.split("/issues")[0];
let authToken = await getAuthToken();
let issueTitle = document.querySelector("h1.gh-header-title").textContent; // Find the title
let branchTitle = formatTitle(issueTitle);
// Append everything and creates the branch
let formData = new FormData();
formData.append("authenticity_token", authToken);
formData.append("name", branchTitle);
formData.append("branch", MASTER_BRANCH);
formData.append("path_binary", "");
fetch(`${repoUrl}/branches`, {
headers: {
accept:
"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"accept-language": "pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7",
"cache-control": "max-age=0",
"content-type": "application/x-www-form-urlencoded",
"sec-fetch-dest": "document",
"sec-fetch-mode": "navigate",
"sec-fetch-site": "same-origin",
"sec-fetch-user": "?1",
"upgrade-insecure-requests": "1",
},
referrer: `${repoUrl}`,
referrerPolicy: "no-referrer-when-downgrade",
body: new URLSearchParams(formData).toString(),
method: "POST",
mode: "cors",
credentials: "include",
});
}
// Create a button to create a branch
let createBranchButton = document.createElement("a");
createBranchButton.className = "btn btn-sm btn-primary m-0 ml-2 ml-md-2";
createBranchButton.innerText = "Create branch!";
createBranchButton.onclick = async () => {
createBranchButton.innerText = "Creating...";
await createBranchFromIssue();
createBranchButton.innerText = "Create branch!";
};
// Append it
let newIssueButton = document.querySelector(
"#partial-discussion-header > div.gh-header-show > div > div > a"
);
newIssueButton.parentElement.appendChild(createBranchButton);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment