Skip to content

Commit

Permalink
Merge pull request #2694 from salesforce-ux/feature/release-notes
Browse files Browse the repository at this point in the history
feature(release-notes): automate release notes
  • Loading branch information
Brian Lonsdorf authored Aug 18, 2017
2 parents 134bad9 + 3666308 commit 6fa56e5
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 32 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
"js-beautify": "1.6.12",
"js-yaml": "3.8.3",
"lodash": "4.17.4",
"lodash-inflection": "1.5.0",
"lodash.omit": "4.5.0",
"lodash.range": "3.2.0",
"lodash.reverse": "4.0.1",
Expand All @@ -115,6 +116,7 @@
"run-sequence": "1.2.2",
"semver": "5.3.0",
"sinon": "2.1.0",
"stream-exhaust": "1.0.1",
"strip-ansi": "3.0.1",
"strip-indent": "2.0.0",
"stylelint": "7.10.1",
Expand Down
8 changes: 3 additions & 5 deletions scripts/dist.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,9 @@ async.series([
* Make release notes
*/
(done) =>
releaseNotes({
isInternal: packageJSON.config.slds.internal,
outStream: fs.createWriteStream(distPath('RELEASENOTES.md')),
callback: done
}),
releaseNotes({ isInternal: packageJSON.config.slds.internal })
.pipe(fs.createWriteStream(distPath('RELEASENOTES.md')))
.on('finish', () => done()),

/**
* Cleanup the package.json
Expand Down
37 changes: 17 additions & 20 deletions scripts/npm/__tests__/release-notes.spec.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,32 @@
const releaseNotes = require('../release-notes')
const fs = require('fs')
const through = require('through2');
const exhaustively = require('stream-exhaust');

describe('Release Notes', () => {
it('generates notes for internal builds', (done) => {
let data = ''
const reader = through((chunk, enc, done) => done(null, data+=chunk))
releaseNotes({
isInternal: true,
outStream: reader,
callback: () => {
expect(data).toContain('Bug Fixes')
expect(data).toContain('design-system-internal')
expect(data.length).toBeGreaterThan(100)
done()
}
const reader = exhaustively(through((chunk, enc, done) => done(null, data+=chunk)))
releaseNotes({ isInternal: true })
.pipe(reader)
.on('end', () => {
expect(data).toContain('Bug Fixes')
expect(data).toContain('design-system-internal')
expect(data.length).toBeGreaterThan(100)
done()
})
})

it('generates notes for external builds', (done) => {
let data = ''
const reader = through((chunk, enc, done) => done(null, data+=chunk))
releaseNotes({
isInternal: false,
outStream: reader,
callback: () => {
expect(data).toContain('Bug Fixes')
expect(data).not.toContain('design-system-internal')
expect(data.length).toBeGreaterThan(100)
done()
}
const reader = exhaustively(through((chunk, enc, d) => d(null, data+=chunk)))
releaseNotes({ isInternal: false })
.pipe(reader)
.on('end', () => {
expect(data).toContain('Bug Fixes')
expect(data).not.toContain('design-system-internal')
expect(data.length).toBeGreaterThan(100)
done()
})
})
})
48 changes: 41 additions & 7 deletions scripts/npm/release-notes.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,48 @@
const lodash = require('lodash')
const _ = lodash.mixin(require("lodash-inflection"))
const {fromNullable} = require('data.either')
const conventionalChangelog = require('conventional-changelog');
const through = require('through2');
const I = require('immutable');

const replaceInternal = str =>
str.replace(/design-system/ig, 'design-system-internal');

const replaceRepo = isInternal => (chunk, enc, callback) =>
callback(null, isInternal ? replaceInternal(String(chunk)) : chunk);
const getSubject = line =>
fromNullable(String(line).match(/\*\*(.*)\*\*/ig))
.map(xs => xs[0])
.getOrElse('')

module.exports = ({isInternal, outStream, callback}) =>
conventionalChangelog({ preset: 'angular', releaseCount: 0 })
.pipe(through(replaceRepo(isInternal)))
.pipe(outStream)
.on('finish', callback);
const normalize = x => _.pluralize(_.kebabCase(x))

const getKeyAndValue = line =>
[normalize(getSubject(line)), _.last(line.split('**'))]

const groupChunks = str =>
str.split('\n').reduce((acc, line) => {
const [key, val] = getKeyAndValue(line)
return acc.get(key)
? acc.update(key, xs => xs.push(val))
: acc.set(key, I.List.of(val))
}, I.OrderedMap())
.map((v, k) => `* **${k}**:\n\t* ${v.join('\n\t*')}`)
.join('\n')

const groupRelatedBullets = x =>
x.match(/^\*/) ? groupChunks(x) : x

const replaceRepoAndGroup = isInternal => (chunk, enc, callback) => {
[String(chunk)]
.map(str => isInternal ? replaceInternal(str) : str)
.map(replaced =>
replaced.split(/\n{2,}/g)
.map(groupRelatedBullets)
.join('\n\n')
)
.map(x => x.replace(/<a name(.*)><\/a>/ig, ''))
.map(result => callback(null, result))
}

module.exports = ({isInternal, callback}) =>
conventionalChangelog({ preset: 'angular', releaseCount: 2 })
.pipe(through(replaceRepoAndGroup(isInternal)))

0 comments on commit 6fa56e5

Please sign in to comment.