This repository has been archived by the owner on Sep 10, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
release.js
171 lines (135 loc) · 4.49 KB
/
release.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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/* eslint global-require: 0 */
/* eslint-disable import/no-dynamic-require, no-console */
const fs = require('fs')
const path = require('path')
const { exec, exit, rm, cp, test } = require('shelljs')
const chalk = require('chalk')
const { flowRight: compose } = require('lodash')
const readline = require('readline-sync')
const semver = require('semver')
const glob = require('glob')
const { pascalCase } = require('change-case')
const BIN = './node_modules/.bin'
const {
PACKAGES_SRC_DIR,
PACKAGES_OUT_DIR,
getPackageNames,
} = require('./getPackageNames')
const BASE_PACKAGE_LOC = '../src/basePackage.json'
const consoleLog = console.log.bind(console)
const log = compose(consoleLog, chalk.bold)
const logSuccess = compose(consoleLog, chalk.green.bold)
const logError = compose(consoleLog, chalk.red.bold)
const writeFile = (filepath, string) =>
fs.writeFileSync(filepath, string, 'utf8')
try {
if (exec('git diff-files --quiet').code !== 0) {
logError(
'You have unsaved changes in the working tree. ' +
'Commit or stash changes before releasing.'
)
exit(1)
}
const packageNames = getPackageNames()
let packageName = readline.question('Name of package to release: ')
while (!packageNames.includes(packageName)) {
packageName = readline.question(
`The package "${packageName}" does not exist in this project. ` +
'Choose again: '
)
}
const libraryName = pascalCase(packageName)
const versionLoc = path.resolve(PACKAGES_SRC_DIR, packageName, 'VERSION')
const version = fs.readFileSync(versionLoc, 'utf8').trim()
let nextVersion = readline.question(
`Next version of ${packageName} (current version is ${version}): `
)
while (
!(
!nextVersion ||
(semver.valid(nextVersion) && semver.gt(nextVersion, version))
)
) {
nextVersion = readline.question(
`Must provide a valid version that is greater than ${version}, ` +
'or leave blank to skip: '
)
}
log('Running tests...')
if (exec('yarn run lint && yarn test').code !== 0) {
logError('The test command did not exit cleanly. Aborting release.')
exit(1)
}
logSuccess('Tests were successful.')
const sourceDir = path.resolve(PACKAGES_SRC_DIR, packageName)
const outDir = path.resolve(PACKAGES_OUT_DIR, packageName)
log('Cleaning destination directory...')
rm('-rf', outDir)
log('Compiling source files...')
const sourceFiles = glob
.sync(`${sourceDir}/**/*.js`, {
ignore: `${sourceDir}/node_modules/**/*.js`,
})
.map(to => path.relative(sourceDir, to))
exec(
`cd ${sourceDir} && ` +
'cross-env BABEL_ENV=cjs ' +
`${path.resolve(BIN)}/babel ${sourceFiles.join(' ')} ` +
`--out-dir ${path.resolve(outDir)}`
)
log('Copying additional project files...')
const additionalProjectFiles = ['README.md', '.npmignore']
additionalProjectFiles.forEach(filename => {
const src = path.resolve(sourceDir, filename)
if (!test('-e', src)) return
cp('-Rf', src, outDir)
})
log('Generating package.json...')
const packageConfig = Object.assign(
{ name: packageName, version: nextVersion },
require(BASE_PACKAGE_LOC),
require(path.resolve(sourceDir, 'package.json'))
)
writeFile(
path.resolve(outDir, 'package.json'),
JSON.stringify(packageConfig, null, 2)
)
log(`Building ${packageName}...`)
const runRollup = () => `yarn build:${packageName}`
if (exec(runRollup()).code !== 0) {
exit(1)
}
log(`Preparing ${libraryName}.cjs.js.flow...`)
cp(
'-f',
path.resolve(sourceDir, 'index.js.flow'),
path.resolve(outDir, 'dist', `${libraryName}.cjs.js.flow`)
)
log(`About to publish ${packageName}@${nextVersion} to npm.`)
if (!readline.keyInYN('Sound good? ')) {
log('OK. Stopping release.')
exit(0)
}
log('Publishing...')
if (exec(`cd ${outDir} && npm publish`).code !== 0) {
logError('Publish failed. Aborting release.')
exit(1)
}
logSuccess(`${packageName}@${nextVersion} was successfully published.`)
log('Updating VERSION file...')
writeFile(versionLoc, `${nextVersion}\n`)
log('Committing changes...')
const newTagName = `v${nextVersion}`
exec(`git add ${versionLoc}`)
exec(`git commit -m "${packageName} ${newTagName}"`)
if (packageName === 'recompose') {
log(`Tagging release... (${newTagName})`)
exec(`git tag ${newTagName}`)
}
log('Pushing to GitHub...')
exec('git push')
exec('git push --tags')
logSuccess('Done.')
} catch (error) {
logError('Release failed due to an error', error)
}