Skip to content

Commit

Permalink
Merge pull request #3 from tay1orjones/semantic-release
Browse files Browse the repository at this point in the history
Semantic release support
  • Loading branch information
tay1orjones authored May 19, 2017
2 parents e5decd0 + 20aeb2c commit e548bcf
Show file tree
Hide file tree
Showing 9 changed files with 1,726 additions and 11 deletions.
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v7.8.0
19 changes: 10 additions & 9 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
language: node_js
node_js: "node"
cache: yarn
deploy:
provider: npm
email: taylor.jones826@gmail.com
api_key:
secure: C8/1War3pJajQN42QN0nxusKBJEGIr+b8DxHp6ixp1AO1yXi5xEgHd8sI7BDv3GdwWCrmOa+L/F/p1omVRm4GSuBOeo0Td3Dh5VUf3Gd1OF11mKXP6O0VL9M4/Z9lKExeUA2b/AGTCc3/++TsqBMZwhwcm0nqJ3qX0WrlsJ4RxXrLIDuGujRxy0WYeqbhlE+wn8MbD+HN/WQ5X3Wp2K9s0iNKYzp7x4g19jdIe7V6QVvrxG0dWVgjN/HqBzqALblJFC/X2gIPQm0Cki3hD6FGpEiRPqaiFCs9KkXDcw18NSoFELZasheHkF1aJ01yeGTI0xsfxLcNtFEE40UKhggp46HZAZjOZ3yNJCimnS4JbzO8x2Rc/Fyk6OMeZ2cv1+7z/0Xie2nydSRe5Rp/CLReb/wVteWc2TGivw8JHrsoazrCLzj7vCzoBGHFN4BmHlLfXUtleLdlDxvVNFPV5y/tKDnHpWaZCgtVeivpUbn3WUM/4ICtX8twP/ZIp3/MqZEu057Bkb71irMsVs3w76u9a+KjxBxFDPI8E+0hDfqobf99FYxxf1sRiLTvzTaNss3LtrF3OqAytlgkpq2woPiI7mgMZ/n+4BZmVhj/BHziIfDYdSz9llXvagg6b5gavOM1yDoVRO9oVYZ6yCO8HmekLIyxEuZvhG5pOyciWsgPpA=
on:
tags: true
repo: tay1orjones/hyper-clean
notifications:
email: false
node_js: 'node'
before_script:
- npm prune
after_success:
- npm run semantic-release
branches:
except:
- /^v\d+\.\d+\.\d+$/
61 changes: 61 additions & 0 deletions lib/cz-emoji-adapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
'use strict'

const emojis = require('./emojis');

// Create inquier.js questions object
function createQuestions() {

const choices = emojis.map((emoji) => {
return {
"name": `${emoji.display} - ${emoji.description}`,
"value": emoji.tag
}
});

return [
{
type: 'list',
name: 'type',
message: "Select the type of change you're committing:",
choices: choices
},
{
type: 'input',
name: 'subject',
message: 'Write a short description:'
},
{
type: 'input',
name: 'issueNumber',
message: 'GitHub issue #:'
},
{
type: 'confirm',
name: 'closesIssue',
message: 'Does this commit fully resolve and close the related issue?',
default: false
}
]
}

// Format the git commit message from given answers.
function format(answers) {
const type = answers.type + ' ';
const description = answers.subject.trim() + ',';
const closesIssue = answers.closesIssue ? ' close' : '';
const issueNumber = ' #' + answers.issueNumber;
// console.log(type + description + closesIssue + issueNumber);
return type + description + closesIssue + issueNumber;
}


// Export an object containing a `prompter` method.
// This object is used by `commitizen`.
module.exports = {
prompter: function(cz, commit) {
cz
.prompt(createQuestions())
.then(format)
.then(commit);
}
}
65 changes: 65 additions & 0 deletions lib/emojis.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
[
{
"name": "sparkles",
"tag": ":sparkles:",
"description": "New feature",
"display": "",
"semver": "minor"
},
{
"name": "bug",
"tag": ":bug:",
"description": "Bug fix",
"display": "🐛",
"semver": "minor"
},
{
"name": "zap",
"tag": ":zap:",
"description": "Performance improvement",
"display": "⚡️",
"semver": "minor"
},
{
"name": "memo",
"tag": ":memo:",
"description": "Documentation improvement",
"display": "📝",
"semver": "patch"
},
{
"name": "blue_heart",
"tag": ":blue_heart:",
"description": "Chore task, unrelated to experience or user value",
"display": "💙",
"semver": "patch"
},
{
"name": "art",
"tag": ":art:",
"description": "Style/formatting code improvements",
"display": "🎨",
"semver": "patch"
},
{
"name": "hammer",
"tag": ":hammer:",
"description": "Refactor code",
"display": "🔨",
"semver": "patch"
},
{
"name": "white_check_mark",
"tag": ":white_check_mark:",
"description": "Tests, adding or improving",
"display": "",
"semver": "patch"
},
{
"name": "boom",
"tag": ":boom:",
"description": "Breaking change, bumps major version",
"display": "💥",
"semver": "major"
}
]
50 changes: 50 additions & 0 deletions lib/semantic-release-plugins/analyze.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Heavy inspiration from the default implementation:
// https://github.com/semantic-release/commit-analyzer/blob/1821a51841329a468f85f7077f6ceed62ec57cf5/src/index.js

var emojis = require('../emojis');

module.exports = function (pluginConfig, {commits}, cb) {
let type = null;
let semanticEmoji = {
"major": [
"boom"
],
"minor": [
"sparkles",
"bug",
"zap"
],
"patch": [
"memo",
"blue_heart",
"art",
"hammer",
"white_check_mark"
]
};

commits

.map((commit) => {
return commit.message.split(":")[1];
})

.every((currentEmojiName) => {
if (currentEmojiName) {

// find the proper semver string from emojis.json
type = emojis.find((emoji) => {
return emoji.name === currentEmojiName;
}).semver;

return (type === "major") ? false : true;

} else {

return false;

}
});

cb(null, type)
}
98 changes: 98 additions & 0 deletions lib/validate-commit-msg.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#!/usr/bin/env node

// Heavy inspiration from https://github.com/kentcdodds/validate-commit-msg

'use strict';

var fs = require('fs');
var path = require('path');
var findParentDir = require('find-parent-dir');
var chalk = require('chalk');
var emojis = require('./emojis');

// fixup! and squash! are part of Git, commits tagged with them are not intended
// to be merged, cf. https://git-scm.com/docs/git-commit
// https://regex101.com/r/xg2yHR/1
// TODO: Improve so that non-word chars are allowed
// example: '.nvmrc' or 'semantic-release' both fail currently
var PATTERN = /^((fixup! |squash! )?(:\w+:){1}((\s\w+)+),(\s\w+)?\s#\d+)(?:\n|$)/;
var MERGE_COMMIT_PATTERN = /^Merge /;

// declare helper functions
var bufferToString = function (buffer) {
return hasToString(buffer) && buffer.toString();
};

var hasToString = function (x) {
return x && typeof x.toString === 'function';
};

var error = function() {
console.error(chalk.red.bold(arguments[0]));
};

var warn = function () {
console.warn(chalk.yellow(arguments[0]));
};

// read/parse the commit message
var commitMsgPath = path.resolve("./", process.env.GIT_PARAMS);
fs.readFile(commitMsgPath, function readFile(err, buffer) {
if(err && err.code !== 'ENOENT') {
throw err;
}

var isFile = !err;
var message = (
isFile
? bufferToString(buffer)
: commitMsgPath
);

// validate that it's in the right format (regex)
if (message === '') {
error('Aborting commit due to empty commit message.');
process.exit(1);
}

if (MERGE_COMMIT_PATTERN.test(message)) {
warn('Merge commit detected, bypassing commit validation');
process.exit(0);
}

if (!PATTERN.test(message)) {
error('Commit messages in this repo must be in the following format:\
\n\n :emoji: short description here, close #45\
\n\nNeed some help? Take a look at this guide:\
\nhttps://git.io/vHvYk');
process.exit(1);
}

// test for valid type
var commitEmoji = message.split(":")[1];
var isValidEmoji = false;
for (let emoji of emojis) {
if (emoji.name === commitEmoji) {
isValidEmoji = true;
}
}

if (!isValidEmoji) {
var emojiList='';
for (let emoji of emojis) {
emojiList += `${emoji.display} ${emoji.tag} - ${emoji.description} \n`;
}

error(`:${commitEmoji}: is not an allowed emoji.\
\n\nAllowed emojis are:\
\n${emojiList}\
\n\nNeed some help? Take a look at this guide:\
\nhttps://git.io/vHvYk`);
process.exit(1);
}

// // for testing:
// console.log(chalk.green.bold("PASSED: WOULD HAVE COMMITTED"));
// process.exit(1);

});
23 changes: 22 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hyper-clean",
"version": "1.0.1",
"version": "0.0.0-development",
"description": "A clean theme for hyper!",
"main": "index.js",
"author": {
Expand All @@ -19,7 +19,28 @@
"hyperterm",
"clean"
],
"config": {
"commitizen": {
"path": "./lib/cz-emoji-adapter"
}
},
"bin": {
"validate-commit-msg": "./lib/validate-commit-msg.js"
},
"scripts": {
"commitmsg": "./lib/validate-commit-msg.js",
"semantic-release": "semantic-release pre && npm publish && semantic-release post"
},
"release": {
"analyzeCommits": "./lib/semantic-release-plugins/analyze"
},
"dependencies": {
"ibm-design-colors": "^2.0.3"
},
"devDependencies": {
"chalk": "^1.1.3",
"find-parent-dir": "^0.3.0",
"husky": "^0.13.3",
"semantic-release": "^6.3.6"
}
}
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# hyper-clean
# hyper-clean [![Travis](https://img.shields.io/travis/tay1orjones/hyper-clean.svg?style=flat-square)](https://travis-ci.org/tay1orjones/hyper-clean) [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=flat-square)](https://github.com/semantic-release/semantic-release)

> A clean [Hyper](https://hyper.is) theme, with [IBM Design colors](https://github.com/IBM-Design/colors)
Expand Down
Loading

0 comments on commit e548bcf

Please sign in to comment.