2021-10-04 13:17:29 +02:00
|
|
|
/**
|
2021-10-04 14:25:11 +02:00
|
|
|
* The release script. This must be called with zx from the repo's root.
|
2021-10-04 13:17:29 +02:00
|
|
|
* Example:
|
|
|
|
* ```
|
|
|
|
* $ cd /path/to/repo
|
2021-10-04 14:25:11 +02:00
|
|
|
* $ yarn run release 0.4.2
|
2021-10-04 13:17:29 +02:00
|
|
|
* ```
|
|
|
|
*/
|
2023-08-06 10:15:37 +02:00
|
|
|
import * as path from 'path'
|
2021-08-05 23:15:00 +02:00
|
|
|
import {readFileSync, writeFileSync} from 'fs'
|
2023-08-07 17:08:04 +02:00
|
|
|
import {$, argv} from '@cspotcode/zx'
|
2021-08-04 21:51:25 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* This script publishes all packages to npm.
|
|
|
|
*
|
|
|
|
* It assigns the same version number to all packages (like lerna's fixed mode).
|
|
|
|
**/
|
2021-08-04 22:56:03 +02:00
|
|
|
const packagesToBuild = [
|
|
|
|
'theatre',
|
|
|
|
'@theatre/dataverse',
|
2021-09-05 23:07:02 +02:00
|
|
|
'@theatre/react',
|
2021-09-30 21:59:52 +02:00
|
|
|
'@theatre/browser-bundles',
|
2022-07-07 22:12:30 +02:00
|
|
|
'@theatre/r3f',
|
2023-01-22 18:51:55 +01:00
|
|
|
'theatric',
|
2021-08-04 22:56:03 +02:00
|
|
|
]
|
|
|
|
|
|
|
|
const packagesToPublish = [
|
|
|
|
'@theatre/core',
|
|
|
|
'@theatre/studio',
|
|
|
|
'@theatre/dataverse',
|
2021-09-05 23:07:02 +02:00
|
|
|
'@theatre/react',
|
2021-09-30 21:59:52 +02:00
|
|
|
'@theatre/browser-bundles',
|
2022-07-07 22:12:30 +02:00
|
|
|
'@theatre/r3f',
|
2023-01-22 18:51:55 +01:00
|
|
|
'theatric',
|
2021-08-04 22:56:03 +02:00
|
|
|
]
|
|
|
|
|
2021-08-05 23:15:00 +02:00
|
|
|
/**
|
|
|
|
* All these packages will have the same version from monorepo/package.json
|
|
|
|
*/
|
|
|
|
const packagesWhoseVersionsShouldBump = [
|
|
|
|
'.',
|
|
|
|
'theatre',
|
|
|
|
'theatre/core',
|
|
|
|
'theatre/studio',
|
|
|
|
'packages/dataverse',
|
2021-09-05 23:07:02 +02:00
|
|
|
'packages/react',
|
2021-09-30 21:59:52 +02:00
|
|
|
'packages/browser-bundles',
|
2022-07-07 22:12:30 +02:00
|
|
|
'packages/r3f',
|
2023-01-23 23:19:40 +01:00
|
|
|
'packages/theatric',
|
2021-08-05 23:15:00 +02:00
|
|
|
]
|
|
|
|
|
2023-08-06 10:15:37 +02:00
|
|
|
// our packages will check for this env variable to make sure their
|
|
|
|
// prepublish script is only called from the `$ cd /path/to/monorepo; yarn run release`
|
|
|
|
// @ts-ignore ignore
|
|
|
|
process.env.THEATRE_IS_PUBLISHING = true
|
2021-08-04 21:51:25 +02:00
|
|
|
|
2023-08-06 10:15:37 +02:00
|
|
|
// better quote function from https://github.com/google/zx/pull/167
|
|
|
|
$.quote = function quote(arg) {
|
|
|
|
if (/^[a-z0-9/_.-]+$/i.test(arg)) {
|
|
|
|
return arg
|
2021-08-08 10:52:18 +02:00
|
|
|
}
|
2023-08-06 10:15:37 +02:00
|
|
|
return (
|
|
|
|
`$'` +
|
|
|
|
arg
|
|
|
|
.replace(/\\/g, '\\\\')
|
|
|
|
.replace(/'/g, "\\'")
|
|
|
|
.replace(/\f/g, '\\f')
|
|
|
|
.replace(/\n/g, '\\n')
|
|
|
|
.replace(/\r/g, '\\r')
|
|
|
|
.replace(/\t/g, '\\t')
|
|
|
|
.replace(/\v/g, '\\v')
|
|
|
|
.replace(/\0/g, '\\0') +
|
|
|
|
`'`
|
|
|
|
)
|
|
|
|
}
|
2021-08-08 10:52:18 +02:00
|
|
|
|
2023-08-06 10:15:37 +02:00
|
|
|
async function release() {
|
2021-08-04 22:56:03 +02:00
|
|
|
$.verbose = false
|
|
|
|
const gitTags = (await $`git tag --list`).toString().split('\n')
|
2021-08-04 21:51:25 +02:00
|
|
|
|
2021-08-05 23:15:00 +02:00
|
|
|
const version = argv._[argv._.length - 1]
|
|
|
|
if (typeof version !== 'string') {
|
|
|
|
console.error(
|
2021-10-04 14:25:11 +02:00
|
|
|
`You need to specify a version, like: $ yarn release 1.2.0-rc.4`,
|
2021-08-05 23:15:00 +02:00
|
|
|
)
|
|
|
|
process.exit(1)
|
2021-08-07 23:39:27 +02:00
|
|
|
} else if (!version.match(/^[0-9]+\.[0-9]+\.[0-9]+(\-(dev|rc)\.[0-9]+)?$/)) {
|
2021-08-05 23:15:00 +02:00
|
|
|
console.error(`Use a semver version, like 1.2.3-rc.4. Provided: ${version}`)
|
|
|
|
process.exit(1)
|
|
|
|
}
|
|
|
|
|
2023-08-07 17:08:04 +02:00
|
|
|
const previousVersion = require('../../package.json').version
|
2021-08-05 23:15:00 +02:00
|
|
|
|
|
|
|
if (version === previousVersion) {
|
|
|
|
console.error(`Version ${version} is already assigned to root/package.json`)
|
|
|
|
process.exit(1)
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gitTags.some((tag) => tag === version)) {
|
|
|
|
console.error(`There is already a git tag for version ${version}`)
|
|
|
|
process.exit(1)
|
|
|
|
}
|
2021-08-05 22:54:19 +02:00
|
|
|
|
2021-10-01 11:11:45 +02:00
|
|
|
let npmTag = 'latest'
|
|
|
|
if (version.match(/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/)) {
|
|
|
|
console.log('npm tag: latest')
|
|
|
|
} else {
|
|
|
|
const matches = version.match(
|
|
|
|
/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\-(dev|rc|beta)\.[0-9]{1,3}$/,
|
|
|
|
)
|
|
|
|
if (!matches) {
|
|
|
|
console.log(
|
|
|
|
'Invalid version. Currently xx.xx.xx or xx.xx.xx-(dev|rc|beta).xx is allowed',
|
|
|
|
)
|
|
|
|
process.exit(1)
|
|
|
|
}
|
2021-10-01 12:33:36 +02:00
|
|
|
npmTag = matches[1]
|
2021-10-01 11:11:45 +02:00
|
|
|
console.log('npm tag: ' + npmTag)
|
|
|
|
}
|
2021-08-04 22:56:03 +02:00
|
|
|
|
|
|
|
if ((await $`git status -s`).toString().length > 0) {
|
|
|
|
console.error(`Git working directory contains uncommitted changes:`)
|
|
|
|
$.verbose = true
|
|
|
|
await $`git status -s`
|
|
|
|
console.log('Commit/stash them and try again.')
|
|
|
|
process.exit(1)
|
|
|
|
}
|
2021-08-04 21:51:25 +02:00
|
|
|
|
2021-08-04 22:56:03 +02:00
|
|
|
$.verbose = true
|
2021-08-05 22:54:19 +02:00
|
|
|
if (argv['skip-lint'] !== true) {
|
|
|
|
console.log('Running a typecheck and lint pass')
|
2021-10-08 11:41:33 +02:00
|
|
|
await Promise.all([$`yarn run typecheck`, $`yarn run lint:all`])
|
2021-08-05 22:54:19 +02:00
|
|
|
} else {
|
|
|
|
console.log('Skipping typecheck and lint')
|
|
|
|
}
|
2021-08-04 21:51:25 +02:00
|
|
|
|
2021-08-07 23:30:07 +02:00
|
|
|
const skipTypescriptEmit = argv['skip-ts'] === true
|
|
|
|
|
2021-08-05 23:15:00 +02:00
|
|
|
console.log('Assigning versions')
|
2022-06-09 19:05:25 +02:00
|
|
|
await writeVersionsToPackageJSONs(version)
|
2021-08-04 22:56:03 +02:00
|
|
|
|
|
|
|
console.log('Building all packages')
|
2021-08-04 21:51:25 +02:00
|
|
|
await Promise.all(
|
2021-08-07 23:30:07 +02:00
|
|
|
packagesToBuild.map((workspace) =>
|
|
|
|
skipTypescriptEmit
|
|
|
|
? $`yarn workspace ${workspace} run build:js`
|
|
|
|
: $`yarn workspace ${workspace} run build`,
|
2021-08-04 22:56:03 +02:00
|
|
|
),
|
|
|
|
)
|
|
|
|
|
2021-08-05 23:15:00 +02:00
|
|
|
// temporarily rolling back the version assignments to make sure they don't show
|
|
|
|
// up in `$ git status`. (would've been better to just ignore hese particular changes
|
|
|
|
// but i'm lazy)
|
|
|
|
await restoreVersions()
|
|
|
|
|
2021-08-04 22:56:03 +02:00
|
|
|
console.log(
|
|
|
|
'Checking if the build produced artifacts that must first be comitted to git',
|
2021-08-04 21:51:25 +02:00
|
|
|
)
|
2021-08-04 22:56:03 +02:00
|
|
|
$.verbose = false
|
|
|
|
if ((await $`git status -s`).toString().length > 0) {
|
|
|
|
$.verbose = true
|
|
|
|
await $`git status -s`
|
2021-08-05 23:15:00 +02:00
|
|
|
console.error(`Git directory contains uncommitted changes.`)
|
2021-08-04 22:56:03 +02:00
|
|
|
process.exit(1)
|
|
|
|
}
|
|
|
|
|
|
|
|
$.verbose = true
|
2021-08-04 21:51:25 +02:00
|
|
|
|
2022-06-09 19:05:25 +02:00
|
|
|
await writeVersionsToPackageJSONs(version)
|
2021-08-06 11:44:20 +02:00
|
|
|
|
2021-08-05 23:15:00 +02:00
|
|
|
console.log('Committing/tagging')
|
|
|
|
|
|
|
|
await $`git add .`
|
2021-08-06 11:15:32 +02:00
|
|
|
await $`git commit -m ${version}`
|
2021-08-05 23:15:00 +02:00
|
|
|
await $`git tag ${version}`
|
|
|
|
|
|
|
|
// if (!gitTags.some((tag) => tag === version)) {
|
|
|
|
// console.log(
|
|
|
|
// `No git tag found for version "${version}". Run \`$ git tag ${version}\` and try again.`,
|
|
|
|
// )
|
|
|
|
// process.exit()
|
|
|
|
// }
|
2021-08-04 22:56:03 +02:00
|
|
|
|
|
|
|
console.log('Publishing to npm')
|
2021-08-04 21:51:25 +02:00
|
|
|
await Promise.all(
|
2021-08-04 22:56:03 +02:00
|
|
|
packagesToPublish.map(
|
2021-10-01 11:11:45 +02:00
|
|
|
(workspace) =>
|
|
|
|
$`yarn workspace ${workspace} npm publish --access public --tag ${npmTag}`,
|
2021-08-04 21:51:25 +02:00
|
|
|
),
|
|
|
|
)
|
2023-08-06 10:15:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void release()
|
2021-08-04 21:51:25 +02:00
|
|
|
|
2023-08-06 10:15:37 +02:00
|
|
|
async function writeVersionsToPackageJSONs(monorepoVersion: string) {
|
2021-08-05 23:15:00 +02:00
|
|
|
for (const packagePathRelativeFromRoot of packagesWhoseVersionsShouldBump) {
|
2021-08-04 21:51:25 +02:00
|
|
|
const pathToPackage = path.resolve(
|
|
|
|
__dirname,
|
2023-08-07 17:08:04 +02:00
|
|
|
'../..',
|
2021-08-04 21:51:25 +02:00
|
|
|
packagePathRelativeFromRoot,
|
|
|
|
'./package.json',
|
|
|
|
)
|
|
|
|
|
2021-08-05 23:15:00 +02:00
|
|
|
const original = JSON.parse(
|
|
|
|
readFileSync(pathToPackage, {encoding: 'utf-8'}),
|
|
|
|
)
|
2021-08-04 21:51:25 +02:00
|
|
|
|
2021-08-05 23:15:00 +02:00
|
|
|
const newJson = {...original, version: monorepoVersion}
|
|
|
|
writeFileSync(
|
|
|
|
path.join(pathToPackage),
|
|
|
|
JSON.stringify(newJson, undefined, 2),
|
|
|
|
{encoding: 'utf-8'},
|
|
|
|
)
|
2021-08-06 11:46:46 +02:00
|
|
|
await $`prettier --write ${packagePathRelativeFromRoot + '/package.json'}`
|
2021-08-05 23:15:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function restoreVersions() {
|
|
|
|
const wasVerbose = $.verbose
|
|
|
|
$.verbose = false
|
|
|
|
for (const packagePathRelativeFromRoot of packagesWhoseVersionsShouldBump) {
|
|
|
|
const pathToPackageInGit = packagePathRelativeFromRoot + '/package.json'
|
2021-08-04 21:51:25 +02:00
|
|
|
|
2021-08-05 23:15:00 +02:00
|
|
|
await $`git checkout ${pathToPackageInGit}`
|
2021-08-04 21:51:25 +02:00
|
|
|
}
|
2021-08-05 23:15:00 +02:00
|
|
|
$.verbose = wasVerbose
|
2021-08-04 21:51:25 +02:00
|
|
|
}
|