mirror of
https://github.com/primer/css.git
synced 2024-11-30 11:17:05 +03:00
152 lines
3.9 KiB
JavaScript
Executable File
152 lines
3.9 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
const execa = require('execa')
|
|
const fetch = require('isomorphic-fetch')
|
|
const fse = require('fs-extra')
|
|
const registryUrl = require('registry-url')
|
|
const semver = require('semver')
|
|
|
|
const bin = 'node_modules/.bin/'
|
|
const lernaBin = `${bin}lerna`
|
|
const getPackages = require('./get-packages')
|
|
const getReleaseVersion = require('./get-release-version')
|
|
const revertPackages = require('./revert-packages')
|
|
|
|
const PRERELEASE = 'prerelease'
|
|
const DIST_TAG = 'rc'
|
|
const PRIMER_CSS = 'primer'
|
|
const RELEASE_VERSION = getReleaseVersion(
|
|
PRIMER_CSS,
|
|
process.env.TRAVIS_BRANCH
|
|
)
|
|
|
|
const depFields = [
|
|
'dependencies',
|
|
'devDependencies',
|
|
'optionalDependencies',
|
|
'peerDependencies',
|
|
]
|
|
|
|
const getUpdated = (args) => {
|
|
return execa(lernaBin, ['updated', '--json'], { reject: false })
|
|
.then(res => {
|
|
if (res.stdout == "") {
|
|
console.warn("No packages need updating")
|
|
return []
|
|
} else {
|
|
return JSON.parse(res.stdout)
|
|
}
|
|
})
|
|
.then(updated => updated.map(pkg => pkg.name))
|
|
}
|
|
|
|
const notify = status => {
|
|
return execa('script/notify', [status], {env: process.env})
|
|
.catch(error => {
|
|
console.error('notify error:', error)
|
|
})
|
|
}
|
|
|
|
const writePackage = (pkg) => {
|
|
const {dir} = pkg
|
|
delete pkg.dir
|
|
const json = JSON.stringify(pkg, null, ' ') + '\n'
|
|
pkg.dir = dir
|
|
return fse.writeFile(`${pkg.dir}/package.json`, json, 'utf8')
|
|
.then(() => pkg)
|
|
}
|
|
|
|
const bump = (pkg, by, preid) => {
|
|
if (pkg.name === PRIMER_CSS) {
|
|
pkg.version = RELEASE_VERSION
|
|
}
|
|
|
|
const original = pkg.version
|
|
let version = increment(pkg.version, by, preid)
|
|
return getPackageInfo(pkg.name)
|
|
.then(info => {
|
|
while (version in info.versions) {
|
|
version = increment(version, by, preid)
|
|
}
|
|
console.warn('%s %s -> %s', pkg.name, original, version)
|
|
pkg.version = version
|
|
return writePackage(pkg)
|
|
})
|
|
}
|
|
|
|
const getPackageInfo = (name) => {
|
|
const url = registryUrl() + name
|
|
return fetch(url).then(res => res.json())
|
|
}
|
|
|
|
const increment = (version, by, preid) => {
|
|
const {major, minor, patch} = semver(version)
|
|
const prev = [major, minor, patch].join('.')
|
|
const next = semver.inc(version, by, preid)
|
|
// if this is a prerelease, "revert" major.minor.patch
|
|
// so that only the prerelease id is incremented
|
|
return by === PRERELEASE
|
|
? next.replace(/^\d+\.\d+\.\d+/, prev)
|
|
: next
|
|
}
|
|
|
|
const updateDependants = (pkg, pkgs) => {
|
|
return pkgs.filter(other => {
|
|
return depFields.some(field => {
|
|
if (other[field] && (pkg.name in other[field])) {
|
|
other[field][pkg.name] = pkg.version
|
|
return true
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
revertPackages()
|
|
.then(() => getPackages())
|
|
.then(dirs => {
|
|
return dirs.map(dir => {
|
|
const pkg = require(`../${dir}/package.json`)
|
|
pkg.dir = dir
|
|
return pkg
|
|
})
|
|
})
|
|
.then(pkgs => {
|
|
const by = PRERELEASE
|
|
const preid = DIST_TAG
|
|
return getUpdated()
|
|
.then(updated => {
|
|
console.warn('%d packages updated...', updated.length)
|
|
return pkgs.filter(pkg => updated.includes(pkg.name))
|
|
})
|
|
.then(updated => {
|
|
const changed = new Set(updated)
|
|
return Promise.all(updated.map(pkg => {
|
|
return bump(pkg, by, preid)
|
|
.then(pkg => updateDependants(pkg, pkgs))
|
|
.then(dependants => {
|
|
dependants.forEach(dep => changed.add(dep))
|
|
})
|
|
}))
|
|
.then(() => {
|
|
const tasks = Array.from(changed)
|
|
.map(writePackage)
|
|
return Promise.all(tasks)
|
|
})
|
|
.then(updated => {
|
|
const tasks = updated.map(pkg => {
|
|
return execa('npm', ['publish', '--tag', DIST_TAG], {
|
|
cwd: pkg.dir,
|
|
stdio: 'inherit',
|
|
})
|
|
})
|
|
return Promise.all(tasks)
|
|
})
|
|
.then(() => notify('success'))
|
|
})
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error)
|
|
process.exitCode = 1
|
|
return notify('error')
|
|
})
|
|
.then(() => process.exit())
|