Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
  • Loading branch information
Pavel910 committed Apr 9, 2018
2 parents c55addf + 6ffcd79 commit 1adc6ad
Show file tree
Hide file tree
Showing 19 changed files with 163 additions and 61 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ node_modules
.DS_Store
coverage
.nyc_output
lib/
lib/
yarn.lock
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Plugins are listed in the recommended order:
| 1. | githubVerify | verifies `GH_TOKEN` or `GITHUB_TOKEN` and repo permissions. |
| 2. | npmVerify | verifies `NPM_TOKEN`. |
| 3. | analyzeCommits | analyzes commit history and determines version type. |
| 4. | updatePackageJSON | updates package version and versions of dependencies. |
| 4. | updatePackage | updates package version and versions of dependencies. |
| 5. | releaseNotes | generates release notes for GitHub release. |
| 6. | githubPublish | publishes a new release to GitHub. |
| 7. | npmPublish | publishes the package to npm. |
Expand All @@ -58,7 +58,7 @@ const projectPackages = [
{
name: 'package-1',
location: '/my/project/packages/package-1',
packageJSON: {
package: {
// Here goes the ENTIRE content of `package.json` file
name: 'package-1',
version: '0.0.0-semantically-released',
Expand All @@ -79,7 +79,7 @@ wsr.release({
wsr.npmVerify(),
wsr.analyzeCommits(),
wsr.releaseNotes(),
wsr.updatePackageJSON(),
wsr.updatePackage(),
wsr.githubPublish(),
wsr.npmPublish()
]
Expand All @@ -103,7 +103,7 @@ const packages = PackageUtilities.getPackages(new Repository())
return {
name: pkg.name,
location: pkg.location,
packageJSON: pkg.toJSON()
package: pkg.toJSON()
};
});
```
Expand All @@ -119,7 +119,7 @@ These Flow types will make everything much clearer:
declare type Package = {
name: string,
location: string,
packageJSON: Object
package: Object
};
declare type Params = {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
"p-reduce": "^1.0.0",
"pre-commit": "^1.2.2",
"prettier": "^1.10.2",
"proxyquire": "^2.0.0",
"proxyquire": "2.0.0",
"sinon": "^4.4.2",
"source-map-support": "^0.5.0",
"tempy": "^0.2.1",
Expand Down
81 changes: 81 additions & 0 deletions scripts/merge.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/usr/bin/env node

/**
* [ MAINTAINERS ONLY ]
* This tool checks if there are any commits that are in branch A that are not in branch B
* and merges the branches. You will have to run `git push` yourself to confirm the merge.
*
* This tool is used to merge branches without creating PRs (as GitHub does) and avoid the annoying merge commit.
*/

const execa = require("execa");
const yargs = require("yargs");
const chalk = require("chalk");
const gitLogParser = require("git-log-parser");
const getStream = require("get-stream");

const { argv } = yargs.command("$0 <from> <into>", "merge branches").help();

function log(...args) {
const [format, ...rest] = args;
console.log(
`${chalk.grey("[WGIT]:")} ${format.replace(/%[^%]/g, seq => chalk.magenta(seq))}`,
...rest
);
}

async function getCommits(gitHead) {
Object.assign(gitLogParser.fields, {
hash: "H",
message: "B",
gitTags: "d",
committerDate: { key: "ci", type: Date }
});

return (await getStream.array(
gitLogParser.parse({ _: `${gitHead ? gitHead + ".." : ""}HEAD` })
)).map(commit => {
commit.message = commit.message.trim();
commit.gitTags = commit.gitTags.trim();
return commit;
});
}

(async () => {
const { from, into } = argv;

log("Merging from %s into %s...", from, into);
const options = { stdio: "inherit" };

try {
await execa.shell("git fetch", options);
await execa.shell("git checkout " + into, options);
await execa.shell("git pull", options);
await execa.shell("git checkout " + from, options);

// Count commits on the "from" branch starting from merge-base to HEAD
const commits = await getCommits(into, from);
if (commits.length) {
log(`Found %s commit(s) that need to be merged:`, commits.length);
commits.map(c => {
log(`* ${c.subject} (%s)`, c.commit.short);
});
await execa.shell("git checkout " + into, options);
await execa.shell("git merge " + from, options);
log(
"Merge is complete. You must run %s yourself after you have verified everything is in order.",
"git push"
);
} else {
log(
"No new commits were found in branch %s that are not already in branch %s.",
from,
into
);
}
log("Exiting.");
} catch (err) {
console.error(err);
process.exit(1);
}
})();
4 changes: 2 additions & 2 deletions scripts/release.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ const config = {
// Make sure "main" field does not start with `src/`
({ packages, logger }, next) => {
packages.map(pkg => {
const json = pkg.packageJSON;
const json = pkg.package;
if (json.main && (json.main.startsWith("src/") || json.main.startsWith("./src/"))) {
logger.log(`Updating \`main\` field of %s`, pkg.name);
json.main = json.main.replace("src/", "lib/");
}
});
next();
},
wsr.updatePackageJSON(),
wsr.updatePackage(),
({ packages }, next) => {
packages.map(pkg => {
if (pkg.nextRelease.version === "1.0.0") {
Expand Down
4 changes: 2 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import githubPublish from "./plugins/github/publish";
import npmVerify from "./plugins/npm/verify";
import npmPublish from "./plugins/npm/publish";
import releaseNotes from "./plugins/releaseNotes";
import updatePackageJSON from "./plugins/updatePackageJSON";
import updatePackage from "./plugins/updatePackage";

const release = async config => {
const { params, plugins } = await buildParams(config);
Expand All @@ -37,6 +37,6 @@ export {
npmVerify,
npmPublish,
releaseNotes,
updatePackageJSON,
updatePackage,
getPackage
};
27 changes: 19 additions & 8 deletions src/plugins/npm/publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import execa from "execa";
import path from "path";
import fs from "fs-extra";

export default () => {
export default (config = {}) => {
const { registry, tag } = config;

return async ({ packages, logger, config }, next) => {
for (let i = 0; i < packages.length; i++) {
const pkg = packages[i];
Expand All @@ -11,24 +13,33 @@ export default () => {
}

logger.log(
"Publishing %s version %s to npm registry",
"Publishing %s version %s to npm registry %s",
pkg.name,
pkg.nextRelease.version
pkg.nextRelease.version,
registry
);

const command = [
`npm publish`,
tag ? `--tag ${tag}` : null,
registry ? `--registry ${registry}` : null,
pkg.location
]
.filter(v => v)
.join(" ");

if (config.preview) {
logger.log(`DRY: %s`, `npm publish ${pkg.location}`);
logger.log(`DRY: %s`, command);
} else {
try {
// write the updated package.json to disk before publishing
fs.writeJsonSync(path.join(pkg.location, "package.json"), pkg.packageJSON, {
fs.writeJsonSync(path.join(pkg.location, "package.json"), pkg.package, {
spaces: 2
});
// We need to unset the `npm_` env variables to make sure local `.npmrc` is being read.
// This is required when running scripts with yarn: https://github.com/yarnpkg/yarn/issues/4475
const shell = await execa.shell(
`unset $(env | awk -F= '$1 ~ /^npm_/ {print $1}') && npm publish ${
pkg.location
}`
`unset $(env | awk -F= '$1 ~ /^npm_/ {print $1}') && ${command}`
);
logger.log(shell.stdout);
pkg.npmPublish = {
Expand Down
10 changes: 7 additions & 3 deletions src/plugins/npm/verify.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import execa from "execa";
import fs from "fs-extra";

export default () => {
export default (config = {}) => {
const { registry = "//registry.npmjs.org" } = config;

return async ({ logger, config }, next) => {
if (config.preview) {
return next();
Expand All @@ -14,10 +16,12 @@ export default () => {

logger.log("Verifying access to NPM...");
try {
await fs.appendFile("./.npmrc", `\n//registry.npmjs.org/:_authToken=${NPM_TOKEN}`);
await fs.appendFile("./.npmrc", `\n${registry}/:_authToken=${NPM_TOKEN}`);
// We need to unset the `npm_` env variables to make sure local `.npmrc` is being read.
// This is required when running scripts with yarn: https://github.com/yarnpkg/yarn/issues/4475
await execa.shell("unset $(env | awk -F= '$1 ~ /^npm_/ {print $1}') && npm whoami");
await execa.shell(
`unset $(env | awk -F= '$1 ~ /^npm_/ {print $1}') && npm whoami --registry ${registry}`
);
next();
} catch (err) {
throw new Error("EINVALIDNPMTOKEN: " + err.message);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ export default () => {
}

// Update package.json data
pkg.packageJSON.version = pkg.nextRelease.version;
updateDeps(pkg.packageJSON.dependencies, packages);
updateDeps(pkg.packageJSON.devDependencies, packages);
pkg.package.version = pkg.nextRelease.version;
updateDeps(pkg.package.dependencies, packages);
updateDeps(pkg.package.devDependencies, packages);
}

next();
Expand Down
4 changes: 2 additions & 2 deletions src/utils/buildParams.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ export default async config => {
params.packages.map(pkg => {
if (
!pkg.hasOwnProperty("name") ||
!pkg.hasOwnProperty("packageJSON") ||
!pkg.hasOwnProperty("package") ||
!pkg.hasOwnProperty("location")
) {
throw new Error(
`EINVALIDPACKAGE: Packages MUST contain \`name\`, \`location\` and \`packageJSON\` keys.`
`EINVALIDPACKAGE: Packages MUST contain \`name\`, \`location\` and \`package\` keys.`
);
}
});
Expand Down
4 changes: 2 additions & 2 deletions src/utils/compose.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
* @param {Array<Function>} functions functions
* @return {Function}
*/
export default function (functions: Array<Function> = []): Function {
return function (params: mixed): Promise<mixed> {
export default function(functions: Array<Function> = []): Function {
return function(params: mixed): Promise<mixed> {
// Create a clone of function chain to prevent modifying the original array with `shift()`
const chain = [...functions];
return new Promise((parentResolve, parentReject) => {
Expand Down
4 changes: 2 additions & 2 deletions src/utils/getPackage.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import readPkg from "read-pkg";
/**
* Get a single package
* @param config
* @returns {{name: string, location: string, packageJSON}}
* @returns {{name: string, location: string, package}}
*/
export default (config = {}) => {
const root = config.root || process.cwd();
const pkg = readPkg.sync(root);
return {
name: pkg.name,
location: root,
packageJSON: pkg
package: pkg
};
};
9 changes: 6 additions & 3 deletions tests/analyzeCommits.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,13 +168,16 @@ describe("analyzeCommits plugin test", function() {

const isRelevant = (pkg, commit) => {
if (commit.message.match(/affects:(.*)/)) {
return RegExp.$1.split(",").map(n => n.trim()).filter(name => pkg.name === name).length;
return RegExp.$1
.split(",")
.map(n => n.trim())
.filter(name => pkg.name === name).length;
}
};
release = compose([analyzeCommitsFactory({isRelevant})]);
release = compose([analyzeCommitsFactory({ isRelevant })]);

const params = {
packages: [{ name: "package-1" }, { name: "package-2" }, {name: "package-3"}],
packages: [{ name: "package-1" }, { name: "package-2" }, { name: "package-3" }],
logger,
git: new Git(),
config: {
Expand Down
14 changes: 7 additions & 7 deletions tests/buildParams.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ describe("build params test", () => {

it("should build a valid default `params` object", async () => {
const config = {
packages: [{ name: "package-1", location: "", packageJSON: {} }],
packages: [{ name: "package-1", location: "", package: {} }],
tagFormat
};

Expand Down Expand Up @@ -42,7 +42,7 @@ describe("build params test", () => {
preview: true,
repositoryUrl: "test",
branch: "development",
packages: [{ name: "package-1", location: "", packageJSON: {} }],
packages: [{ name: "package-1", location: "", package: {} }],
tagFormat
};

Expand Down Expand Up @@ -70,7 +70,7 @@ describe("build params test", () => {
preview: true,
repositoryUrl: "test",
branch: "development",
packages: [{ name: "package-1", location: "", packageJSON: {} }],
packages: [{ name: "package-1", location: "", package: {} }],
tagFormat
};

Expand All @@ -94,7 +94,7 @@ describe("build params test", () => {

it("should convert `tagFormat` string into a function", async () => {
const config = {
packages: [{ name: "package-1", location: "", packageJSON: {} }],
packages: [{ name: "package-1", location: "", package: {} }],
tagFormat: "v${version}"
};

Expand All @@ -105,7 +105,7 @@ describe("build params test", () => {

it("should use the given `tagFormat` function", async () => {
const config = {
packages: [{ name: "package-1", location: "", packageJSON: {} }],
packages: [{ name: "package-1", location: "", package: {} }],
tagFormat
};

Expand All @@ -115,7 +115,7 @@ describe("build params test", () => {
});

it("should convert a single package to an array of packages", async () => {
const pkg1 = { name: "package-1", location: "", packageJSON: {} };
const pkg1 = { name: "package-1", location: "", package: {} };
const { params } = await buildParams({
packages: pkg1,
tagFormat
Expand All @@ -133,7 +133,7 @@ describe("build params test", () => {

it("should throw error if an invalid package structure is found", async () => {
const config1 = { packages: [{ name: "package-1" }], tagFormat };
const config2 = { packages: [{ packageJSON: "package-1" }], tagFormat };
const config2 = { packages: [{ package: "package-1" }], tagFormat };
const config3 = { packages: [{ location: "package-1" }], tagFormat };

return Promise.all([
Expand Down
Loading

0 comments on commit 1adc6ad

Please sign in to comment.