Skip to content

Instantly share code, notes, and snippets.

@douglascayers
Last active September 14, 2023 15:30
Show Gist options
  • Star 24 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save douglascayers/d47e525dbd1e7149bafa65939f350baf to your computer and use it in GitHub Desktop.
Save douglascayers/d47e525dbd1e7149bafa65939f350baf to your computer and use it in GitHub Desktop.
Export and import GitHub labels between projects by running JavaScript in the browser console to automate clicks.
/**
* Inspired by @MoOx original script: https://gist.github.com/MoOx/93c2853fee760f42d97f
* Adds file download per @micalevisk https://gist.github.com/MoOx/93c2853fee760f42d97f#gistcomment-2660220
*
* Changes include:
* - Get the description from the `title` attribute instead of `aria-label` (doesn't exist anymore)
* - Use style.backgroundColor and parse the rgb(...) to hex (rather than regex parsing of 'style' string)
* - Downloads labels to a JSON file named after the webpage to know which GitHub repo they came from.
*
* Last tested 2019-July-27:
* - Chrome 75.0.3770.142
* - Safari 12.1.2
* - macOS 10.14.6
*/
function exportGitHubLabels() {
let labels = [];
[].slice.call( document.querySelectorAll( '.label-link' ) )
.forEach( element => {
labels.push({
name: element.textContent.trim(),
description: element.getAttribute( 'title' ),
color: (
// style.backgroundColor returns "rgb(...)"
// but GitHub expects hex when we import the colors
element.style.backgroundColor
// grab between 'rgb(' and ')'
.substring( 4, element.style.backgroundColor.length - 1 )
// convert comma-delimited string into array of three numbers
.split( ',' )
// reduce array of three numbers into single hex color
.reduce( ( hexValue, rgbValue ) => {
return (
// append next two-digit hex value
hexValue +
// convert decimal to hex
Number( rgbValue ).toString( 16 )
// each number in a hex color is two characters
.padStart( 2, '0' )
);
}, '' )
)
});
});
return labels;
}
function saveDataAsJSON( data, filename ) {
const blob = new Blob( [ JSON.stringify( data, null, 4 ) ], { type: 'text/json' } );
const a = document.createElement( 'a' );
a.download = filename;
a.href = window.URL.createObjectURL( blob );
a.dataset.downloadurl = [ 'text/json', a.download, a.href ].join( ':' );
a.click();
}
saveDataAsJSON( exportGitHubLabels(), document.title + '.json' );
/**
* Inspired by @Isaddo original script: https://gist.github.com/Isaddo/7efebcb673a0957b9c6f07cd14826ea4
* Adds descriptions per @NillerMedDild https://gist.github.com/Isaddo/7efebcb673a0957b9c6f07cd14826ea4#gistcomment-2715349
*
* Changes include:
* - CSS selectors use `js` prefix
*
* Last tested 2019-July-27:
* - Chrome 75.0.3770.142
* - Safari 12.1.2
* - macOS 10.14.6
*/
function createLabel( label ) {
document.querySelector( '.js-new-label-name-input' ).value = label.name;
document.querySelector( '.js-new-label-description-input' ).value = label.description;
document.querySelector( '.js-new-label-color-input' ).value = '#' + label.color;
document.querySelector( '.js-details-target ~ .btn-primary' ).disabled = false;
document.querySelector( '.js-details-target ~ .btn-primary' ).click();
}
function updateLabel( label ) {
let updatedLabel = false;
[].slice.call( document.querySelectorAll( '.js-labels-list-item' ) ).forEach( element => {
if ( element.querySelector( '.js-label-link' ).textContent.trim() === label.name ) {
updatedLabel = true;
element.querySelector( '.js-edit-label' ).click();
element.querySelector( '.js-new-label-name-input' ).value = label.name;
element.querySelector( '.js-new-label-description-input' ).value = label.description;
element.querySelector( '.js-new-label-color-input' ).value = '#' + label.color;
element.querySelector( '.js-edit-label-cancel ~ .btn-primary' ).click();
}
});
return updatedLabel;
}
function createOrUpdate( label ) {
if ( !updateLabel( label ) ) {
createLabel( label );
}
}
[
// YOUR LABELS JSON HERE
].forEach( label => createOrUpdate( label ) );
[
{
"name": "a11y",
"description": "This needs improved accessibility. https://a11yproject.com/",
"color": "20e5d8"
},
{
"name": "bug: crash 💥",
"description": "App crashes and is unusable in a significant way.",
"color": "fbca04"
},
{
"name": "bug: regression ↩️",
"description": "A new version of the app broke something.",
"color": "fbca04"
},
{
"name": "bug 🐞",
"description": "App is not working correctly.",
"color": "fbca04"
},
{
"name": "discussion 💬",
"description": "Discussing usage, best practices, questions, etc.",
"color": "e99695"
},
{
"name": "documentation 📓",
"description": "Related to improving documentation and the wiki.",
"color": "6addf7"
},
{
"name": "enhancement ✨",
"description": "A new feature suggestion or improvement upon an existing feature.",
"color": "84b6eb"
},
{
"name": "salesforce known issue ⚠️",
"description": "A known issue with the Salesforce platform and likely not something the app can address.",
"color": "fcec85"
},
{
"name": "security 🔒",
"description": "Questions, concerns, or suggestions for improving the security of the app.",
"color": "1d76db"
},
{
"name": "status: in progress ❇️",
"description": "Currently being developed for a future release.",
"color": "c2e0c6"
},
{
"name": "status: on hold 💤",
"description": "Work has stopped. There may be one or more blockers or needs more information.",
"color": "c2e0c6"
},
{
"name": "status: resolved ✅",
"description": "This has been addressed in a branch and will be scheduled for release in the assigned milestone.",
"color": "c2e0c6"
}
]
@germanfr
Copy link

The class name of labels has changed. For the export script to work you have to change .label-link to .js-label-link.

@yuvalbl
Copy link

yuvalbl commented Nov 9, 2020

@germanfr is correct 👍

@nilsreichardt
Copy link

The export script doesn't export the colors correct. They are always 00

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment