forked from github/docs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
build-changelog-from-markdown.js
executable file
·130 lines (100 loc) · 4.16 KB
/
build-changelog-from-markdown.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/usr/bin/env node
const fs = require('fs')
const path = require('path')
const { sortBy, reverse } = require('lodash')
const frontmatter = require('../../lib/frontmatter')
const git = require('../../lib/git-utils')
const staticChangelog = path.join(process.cwd(), 'lib/graphql/static/changelog.json')
// values for api
const owner = 'github'
const repo = 'internal-developer.github.com'
const ref = 'heads/master'
const previewsBaseLink = '/graphql/overview/schema-previews'
const changesList = /(\n*[\s\S]*?\n)$/m
// until 2018-02-14, all changelogs used the phrase 'The following changes were made to the GraphQL schema'
const schemaRegexGlobal = new RegExp('(The GraphQL schema includes these changes:|The following changes were made to the GraphQL schema:)' + changesList.source, 'mg')
const previewRegexGlobal = new RegExp('(The .*?preview.*? includes these changes:)' + changesList.source, 'mg')
const upcomingRegexGlobal = new RegExp('(The following changes will be made to the schema:)' + changesList.source, 'mg')
const schemaRegexSingle = new RegExp(schemaRegexGlobal.source, 'm')
const previewRegexSingle = new RegExp(previewRegexGlobal.source, 'm')
const upcomingRegexSingle = new RegExp(upcomingRegexGlobal.source, 'm')
main()
async function main () {
const tree = await git.getTree(owner, repo, ref)
const changelogFiles = tree.filter(entry => entry.path.includes('v4/changelog') && entry.type === 'blob')
const changelog = []
await Promise.all(changelogFiles.map(async (blob) => {
// get the contents of `content/v4/changelog/*` files from internal-developer.github.com
const contents = await git.getContentsForBlob(owner, repo, blob)
const file = blob.path
if (file.endsWith('index.html')) return
process.stdout.write('.')
const date = path.basename(file).replace('-schema-changes.md', '')
const { content } = frontmatter(contents)
// match each section title and list of changes
const schemaChangesMatches = content.match(schemaRegexGlobal)
const previewChangesMatches = content.match(previewRegexGlobal)
const upcomingChangesMatches = content.match(upcomingRegexGlobal)
const entry = {}
// do a little formatting cleanup
entry.date = date
entry.schemaChanges = getEntry(schemaChangesMatches, schemaRegexSingle)
entry.previewChanges = getEntry(previewChangesMatches, previewRegexSingle)
entry.upcomingChanges = getEntry(upcomingChangesMatches, upcomingRegexSingle)
// very first changelog has custom content
if (date === '2017-05-22') {
entry.schemaChanges[0].changes.push('Nothing! The schema was made public!')
}
changelog.push(entry)
}))
// sort by newest entries first
const sortedChangelog = reverse(sortBy(changelog, ['date']))
// write json file
fs.writeFileSync(staticChangelog, JSON.stringify(sortedChangelog, null, 2))
console.log(`\n\nupdated ${staticChangelog}`)
}
function getEntry (matches, regex) {
return matches
? matches.map(match => {
const entry = {}
entry.title = cleanPreviewLinks(match.match(regex)[1])
entry.changes = getChangedItems(match.match(regex)[2])
return entry
})
: []
}
function getChangedItems (string) {
return string
.split('\n*')
.slice(1)
.map(i => i.trim())
}
// do some cleanup of preview links
function cleanPreviewLinks (title) {
const previewMarkup = title.match(/\[(.*?)\]\((.*?)\)/)
if (!previewMarkup) return title
const rawName = previewMarkup[1]
const rawLink = previewMarkup[2]
let cleanName = rawName
let cleanLink = rawLink
// fix two malformed links
if (cleanName.includes('MergeInfoPreview')) {
cleanName = 'Merge info preview'
cleanLink = `${previewsBaseLink}#merge-info-preview`
}
if (cleanName.includes('UpdateRefsPreview')) {
cleanName = 'Update refs preview'
cleanLink = `${previewsBaseLink}#update-refs-preview`
}
cleanName = !cleanName.endsWith('preview')
? `${cleanName} preview`
: cleanName
cleanLink = !cleanLink.endsWith('-preview')
? `${cleanLink}-preview`
: cleanLink
cleanLink = cleanLink
.replace('/v4/previews/', previewsBaseLink)
return title
.replace(rawName, cleanName)
.replace(rawLink, cleanLink)
}