Skip to content

Instantly share code, notes, and snippets.

@keplersj
Last active April 15, 2018 03:46
Show Gist options
  • Save keplersj/8bc7622ea741c0964d12842bfc679c5d to your computer and use it in GitHub Desktop.
Save keplersj/8bc7622ea741c0964d12842bfc679c5d to your computer and use it in GitHub Desktop.
import { createApolloFetch } from "apollo-fetch";
import * as cp from "child_process";
import pify from "pify";
import * as path from "path";
import * as fs from "fs";
import got = require("got");
const restEndpoint = "https://api.github.com";
const uri = "https://api.github.com/graphql";
const token = process.env.GITHUB_TOKEN;
const apolloFetch = createApolloFetch({ uri });
apolloFetch.use(({ request, options }, next) => {
if (!options.headers) {
options.headers = {}; // Create the headers object if needed.
}
options.headers["Authorization"] = `bearer ${token}`;
next();
});
const REPOS_QUERY = `
query {
organization(login: "AtomLinter") {
login
name
url
repositories(first: 100) {
nodes {
name
url
sshUrl
isFork
}
}
}
}
`;
const newTravisConfigs = `
node_js: lts/*
after_success:
# Add apm to the PATH
- export PATH=\${PATH}:\${HOME}/atom/usr/bin/
deploy:
provider: script
skip_cleanup: true
script:
- npx semantic-release
`;
async function main() {
const reposResult = await apolloFetch({
query: REPOS_QUERY
});
if (reposResult.errors) {
console.error(reposResult.errors);
process.exit(1);
}
console.log("Loaded repos from AtomLinter");
// We only want to interact with the actual providers.
const repos: any[] = reposResult.data.organization.repositories.nodes.filter(
repo => Boolean((repo.name as string).match(/linter-/)) && !repo.isFork
);
repos.forEach(async repo => {
console.log(`Cloning AtomLinter/${repo.name}`);
try {
await pify(cp.exec)(`git clone --depth 1 ${repo.sshUrl}`, {
cwd: "./tmp"
});
} catch (e) {
console.log(`Could not clone repo for ${repo.name}. Moving on.`);
return;
}
console.log(`Cloned AtomLinter/${repo.name}`);
console.log(`Checking if ${repo.name} has semantic-release configured`);
let pkgManifest: any;
try {
pkgManifest = JSON.parse(
fs.readFileSync(path.resolve(`./tmp/${repo.name}/package.json`), {
encoding: "utf-8"
})
);
} catch (e) {
console.log(
`Could not parse package manifest for ${repo.name}. Moving on.`
);
return;
}
if (pkgManifest.release) {
console.log(`${repo.name} already has semantic-release configured`);
return;
}
console.log(
`Checking out new branch "kepler/continous-deployment" on ${repo.name}`
);
await pify(cp.exec)(`git checkout -b kepler/continous-deployment`, {
cwd: `./tmp/${repo.name}`
});
console.log(
`Checked out new branch "kepler/continous-deployment" on ${repo.name}`
);
console.log(`Adding new configs to ${repo.name} package manifest`);
pkgManifest["release"] = {
extends: "@semantic-release/apm-config"
};
pkgManifest["commitlint"] = {
extends: ["@commitlint/config-conventional"]
};
pkgManifest["devDependencies"] = {
"@commitlint/cli": "^6.1.3",
"@commitlint/config-conventional": "^6.1.3",
"@commitlint/travis-cli": "^6.1.3",
"@semantic-release/apm-config": "^2.0.1",
husky: "^0.14.3",
"semantic-release": "^15.1.7",
...pkgManifest["devDependencies"]
};
pkgManifest["scripts"] = {
commitmsg: "commitlint -e $GIT_PARAMS",
...pkgManifest["scripts"]
};
await pify(fs.writeFile)(
`./tmp/${repo.name}/package.json`,
JSON.stringify(pkgManifest, null, 2),
{
encoding: "utf-8"
}
);
await pify(cp.exec)(`git add package.json`, {
cwd: `./tmp/${repo.name}`
});
console.log(`Added new configs to ${repo.name} package-manifest`);
if (fs.existsSync(`./tmp/${repo.name}/.travis.yml`)) {
console.log(`Updating Travis CI config for ${repo.name}`);
await pify(fs.writeFile)(
`./tmp/${repo.name}/.travis.yml`,
fs.readFileSync(`./tmp/${repo.name}/.travis.yml`, {
encoding: "utf-8"
}) + newTravisConfigs
);
await pify(cp.exec)(`git add .travis.yml`, {
cwd: `./tmp/${repo.name}`
});
console.log(`Updated Travis CI config for ${repo.name}`);
} else {
console.log(`Could not find Travis CI config for ${repo.name}`);
}
console.log(`Commiting changes to ${repo.name}`);
try {
await pify(cp.exec)(
`git commit -m "build(release): initial adoption of semantic-release and commitlint"`,
{
cwd: `./tmp/${repo.name}`
}
);
} catch (e) {
console.log(`Could not commit changes to ${repo.name}. Moving on.`);
return;
}
console.log(`Committed changes to ${repo.name}`);
console.log(`Creating fork of AtomLinter/${repo.name}`);
const forkResult = await got(
`${restEndpoint}/repos/AtomLinter/${repo.name}/forks`,
{
method: "POST",
json: true,
headers: { Authorization: `token ${token}` }
}
);
console.log(`Fork of ${repo.name} avalible at ${forkResult.body.html_url}`);
console.log(`Adding remote to ${repo.name} repo`);
try {
await pify(cp.exec)(
`git remote set-url remote ${forkResult.body.ssh_url}`,
{
cwd: `./tmp/${repo.name}`
}
);
} catch (e) {
console.log(`Could not add remote ${repo.name}. Moving on.`);
return;
}
console.log(`Added remote to ${repo.name} repo`);
console.log(`Pushing ${repo.name} changes to fork`);
try {
await pify(cp.exec)(
`git push -u fork kepler/continous-deployment:continous-deployment`,
{
cwd: `./tmp/${repo.name}`
}
);
} catch (e) {
console.log(`Could not push ${repo.name} changes to fork. Moving on.`);
return;
}
console.log(`Pushed ${repo.name} changes to fork`);
console.log(`Creating ${repo.name} pull request`);
const prResult = await got(
`${restEndpoint}/repos/AtomLinter/${repo.name}/pulls`,
{
method: "POST",
json: true,
body: {
title:
"Initial Adoption of Continous Deployment using semantic-release",
head: "kepler:continous-deployment",
base: "master",
body: fs.readFileSync("../pull_request_body.md", {
encoding: "utf-8"
}),
maintainer_can_modify: true
},
headers: { Authorization: `token ${token}` }
}
);
console.log(`Created ${repo.name} pull request`);
});
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment