To run this script, download this script to a folder on your computer and run npx zx create-prs.md
.
You must install the following utilities to run this script.
Follow instructions on GitHub CLI. Once you installed, you must run gh auth login
to authenticate your local environment.
Follow instructions on git-xargs. You have to make sure to configure GITHUB_OAUTH_TOKEN
environment variable with a personal access token.
zx
which runs this script requires Node.js 16+.
Here is the code that verifies that all of the utilities are available for this script to run.
const { ok } = await import('assert')
ok(await which('gh'), 'gh utility is missing')
ok(await which('git-xargs'), 'git-xargs is missing')
const m = process.version.match(/(\d+)\.(\d+)\.(\d+)/);
const [major] = m.slice(1).map(_ => parseInt(_));
ok(major >= 16, `Node 16+ required, using ${process.version}`)
You can pass name of the organization as the first argument. The script will prompt you otherwise.
For example: npx zx create-prs.md thefrontside
let {_: [org]} = argv;
if (!org) {
org = await question('What GitHub organization do you want to create pull requests in?')
}
let repoes = await $`gh repo list ${org} --limit=1000 --json=description,url,name,owner,nameWithOwner,languages`;
await $`mkdir -p components`
You can modify the following template to customize how
function template(repo) {
return {
apiVersion: "backstage.io/v1alpha1",
kind: 'Component',
metadata: {
name: slugify(repo.name),
description: repo.description,
},
annotations: {
"github.com/project-slug": repo.nameWithOwner,
},
tags: [...repo.languages.map(language => language.node.name)],
spec: {
type: "service",
owner: repo.owner.login,
lifecycle: "experimental"
}
}
}
for (let repo of JSON.parse(repoes)) {
let content = YAML.stringify(template(repo));
await $`mkdir -p components/${repo.name}`;
let file = $`cat > components/${repo.name}/app-config.yaml`
file.stdin.write(content)
file.stdin.end()
}
These are the utilities used by the template.
/**
* @source: https://gist.github.com/hagemann/382adfc57adbd5af078dc93feef01fe1
**/
function slugify(string) {
const a = 'àáâäæãåāăąçćčđďèéêëēėęěğǵḧîïíīįìıİłḿñńǹňôöòóœøōõőṕŕřßśšşșťțûüùúūǘůűųẃẍÿýžźż·/_,:;'
const b = 'aaaaaaaaaacccddeeeeeeeegghiiiiiiiilmnnnnoooooooooprrsssssttuuuuuuuuuwxyyzzz------'
const p = new RegExp(a.split('').join('|'), 'g')
return string.toString().toLowerCase()
.replace(/\s+/g, '-') // Replace spaces with -
.replace(p, c => b.charAt(a.indexOf(c))) // Replace special characters
.replace(/&/g, '-and-') // Replace & with 'and'
.replace(/[^\w\-]+/g, '') // Remove all non-word characters
.replace(/\-\-+/g, '-') // Replace multiple - with single -
.replace(/^-+/, '') // Trim - from start of text
.replace(/-+$/, '') // Trim - from end of text
}