Skip to content

Commit

Permalink
feat: add execute release feature
Browse files Browse the repository at this point in the history
  • Loading branch information
lekterable committed Apr 20, 2020
1 parent 2ea0435 commit 4e02179
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 19 deletions.
3 changes: 2 additions & 1 deletion .babelrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"presets": ["@babel/preset-env"]
"presets": ["@babel/preset-env"],
"plugins": ["@babel/plugin-transform-runtime"]
}
7 changes: 6 additions & 1 deletion bin/perfekt.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
#!/usr/bin/env node

const { program } = require('commander')
const { changelog } = require('../dist').default
const { changelog, release } = require('../dist')

program
.command('changelog')
.description('generate package changelog')
.action(() => changelog())

program
.command('release <version>')
.description('execute a new release')
.action(version => release(version))

program.parse(process.argv)
25 changes: 25 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@
],
"license": "MIT",
"dependencies": {
"commander": "^5.0.0"
"commander": "^5.0.0",
"semver": "^7.3.2"
},
"devDependencies": {
"@babel/core": "^7.9.0",
"@babel/plugin-transform-runtime": "^7.9.0",
"@babel/preset-env": "^7.9.5",
"@commitlint/cli": "^8.3.5",
"@commitlint/config-conventional": "^8.3.4",
Expand Down
50 changes: 34 additions & 16 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,39 @@
import { exec } from 'child_process'
import semver from 'semver'
import { commitRelease, getCommitDetails, getCommits } from './utils'

const changelog = () =>
exec('git log --format="%H %s"', (_, res) => {
let changelog = '## Latest\n\n'
const commits = res.split('\n').filter(commit => commit)
commits.forEach(commit => {
const {
groups: { hash, title }
} = commit.match(/(?<hash>.{40}) (?<title>.*)/)
const {
groups: { scope }
} = title.match(/(\w*)(?:\((?<scope>.*)\))?:/)
export const changelog = async version => {
const title = version || 'Latest'
const commits = await getCommits()
const latestCommit = getCommitDetails(commits[0])
const isReleaseLatest = latestCommit.scope === 'release'
let changelog = isReleaseLatest ? '' : `## ${title}\n\n`

if (scope !== 'changelog') changelog += `- ${title} ${hash.slice(0, 8)}\n`
})
commits.forEach((commit, index) => {
const { title, scope, hash, message } = getCommitDetails(commit)
const nextCommit = getCommitDetails(commits[index + 1])
const isReleaseNext = nextCommit && nextCommit.scope === 'release'

return process.stdout.write(changelog)
if (scope === 'release') return (changelog += `## ${message}\n\n`)
if (scope !== 'changelog') {
return (changelog += `- ${title} ${hash.slice(0, 8)}\n${
isReleaseNext ? '\n' : ''
}`)
}
})

export default { changelog }
return process.stdout.write(changelog)
}

export const release = version => {
const newVersion = semver.valid(semver.coerce(version))
if (!newVersion) {
return console.error(`Version '${version}' doesnt look right`)
}

try {
changelog(newVersion)
commitRelease(newVersion)
} catch (error) {
console.error(error)
}
}
32 changes: 32 additions & 0 deletions src/utils/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { exec } from 'child_process'

export const commitRelease = version =>
new Promise((resolve, reject) => {
exec(`git commit -m 'chore(release): ${version}'`, (err, res) => {
if (err) return reject(err)
resolve()
})
})

export const getCommits = () =>
new Promise((resolve, reject) =>
exec('git log --format="%H %s"', (err, res) => {
if (err) return reject(err)

const commits = res.split('\n').filter(commit => commit)
resolve(commits)
})
)

export const getCommitDetails = commit => {
if (!commit) return null

const {
groups: { hash, title }
} = commit.match(/(?<hash>.{40}) (?<title>.*)/)
const {
groups: { scope, message }
} = title.match(/(\w*)(?:\((?<scope>.*)\))?: (?<message>.*)/)

return { hash, title, scope, message }
}

0 comments on commit 4e02179

Please sign in to comment.