diff --git a/.scripts/common.js b/.scripts/common.js index 86a64be767..09832ddadd 100644 --- a/.scripts/common.js +++ b/.scripts/common.js @@ -21,7 +21,7 @@ function readPkg(project) { function writePkg(project, pkg) { const packageJsonPath = packagePath(project); const text = JSON.stringify(pkg, null, 2); - return fs.writeFileSync(packageJsonPath, text); + return fs.writeFileSync(packageJsonPath, `${text}\n`); } function packagePath(project) { @@ -133,6 +133,113 @@ function preparePackage(tasks, package, version) { } +function prepareDevPackage(tasks, package, version) { + const projectRoot = projectPath(package); + const pkg = readPkg(package); + + const projectTasks = []; + + if (package !== 'docs') { + if (package !== 'core') { + projectTasks.push({ + title: `${pkg.name}: npm link @ionic/core`, + task: () => execa('npm', ['link', '@ionic/core'], { cwd: projectRoot }) + }); + } + + projectTasks.push({ + title: `${pkg.name}: update ionic/core dep to ${version}`, + task: () => { + updateDependency(pkg, "@ionic/core", version); + writePkg(package, pkg); + } + }); + + projectTasks.push({ + title: `${pkg.name}: build`, + task: () => execa('npm', ['run', 'build'], { cwd: projectRoot }) + }); + + if (package === 'core') { + projectTasks.push({ + title: `${pkg.name}: npm link`, + task: () => execa('npm', ['link'], { cwd: projectRoot }) + }); + } + } + + // Add project tasks + tasks.push({ + title: `Prepare dev build: ${tc.bold(pkg.name)}`, + task: () => new Listr(projectTasks) + }); +} + +function updatePackageVersions(tasks, packages, version) { + packages.forEach(package => { + updatePackageVersion(tasks, package, version); + + tasks.push( + { + title: `${package} update @ionic/core dependency, if present ${tc.dim(`(${version})`)}`, + task: async () => { + if (package !== 'core') { + const pkg = readPkg(package); + updateDependency(pkg, '@ionic/core', version); + writePkg(package, pkg); + } + }, + } + ) + }); +} + + +function updatePackageVersion(tasks, package, version) { + const projectRoot = projectPath(package); + + tasks.push( + { + title: `${package}: update package.json ${tc.dim(`(${version})`)}`, + task: async () => { + await execa('npm', ['version', version], { cwd: projectRoot }); + } + } + ); +} + +function publishPackages(tasks, packages, version, tag = 'latest') { + // first verify version + packages.forEach(package => { + if (package === 'core') { + return; + } + + tasks.push({ + title: `${package}: check version (must match: ${version})`, + task: () => { + const pkg = readPkg(package); + + if (version !== pkg.version) { + throw new Error(`${pkg.name} version ${pkg.version} must match ${version}`); + } + } + }); + }); + + // next publish + packages.forEach(package => { + const projectRoot = projectPath(package); + + tasks.push({ + title: `${package}: publish to ${tag} tag`, + task: async () => { + await execa('npm', ['publish', '--tag', tag], { cwd: projectRoot }); + }, + }); + }); +} + function updateDependency(pkg, dependency, version) { if (pkg.dependencies && pkg.dependencies[dependency]) { pkg.dependencies[dependency] = version; @@ -151,13 +258,19 @@ function isVersionGreater(oldVersion, newVersion) { module.exports = { + checkGit, isValidVersion, isVersionGreater, - readPkg, - writePkg, - rootDir, - projectPath, - checkGit, packages, - preparePackage + packagePath, + prepareDevPackage, + preparePackage, + projectPath, + publishPackages, + readPkg, + rootDir, + updateDependency, + updatePackageVersion, + updatePackageVersions, + writePkg, }; diff --git a/.scripts/prepare.js b/.scripts/prepare.js index 32adac9b8f..6111b1e424 100644 --- a/.scripts/prepare.js +++ b/.scripts/prepare.js @@ -6,7 +6,6 @@ const tc = require('turbocolor'); const execa = require('execa'); const inquirer = require('inquirer'); const Listr = require('listr'); -const fs = require('fs-extra'); const semver = require('semver'); const common = require('./common'); const path = require('path'); @@ -108,7 +107,7 @@ async function preparePackages(packages, version) { // add update package.json of each project packages.forEach(package => { - updatePackageVersion(tasks, package, version); + common.updatePackageVersion(tasks, package, version); }); // generate changelog @@ -155,20 +154,6 @@ function validateGit(tasks, version) { ); } -function updatePackageVersion(tasks, package, version) { - const projectRoot = common.projectPath(package); - const pkg = common.readPkg(package); - - tasks.push( - { - title: `${pkg.name}: update package.json ${tc.dim(`(${version})`)}`, - task: async () => { - await execa('npm', ['version', version], { cwd: projectRoot }); - } - } - ); -} - function generateChangeLog(tasks) { tasks.push({ diff --git a/.scripts/release-dev.js b/.scripts/release-dev.js new file mode 100644 index 0000000000..12960e0d7c --- /dev/null +++ b/.scripts/release-dev.js @@ -0,0 +1,102 @@ +const tc = require('turbocolor'); +const semver = require('semver'); +const execa = require('execa'); +const inquirer = require('inquirer'); +const Listr = require('listr'); +const fs = require('fs-extra'); + +const common = require('./common'); + +const DIST_TAG = 'dev'; + +async function main() { + const { packages } = common; + + const orgPkg = packages.map(package => { + const packageJsonPath = common.packagePath(package); + return { + filePath: packageJsonPath, + packageContent: fs.readFileSync(packageJsonPath, 'utf-8') + } + }); + + try { + const originalVersion = common.readPkg('core').version; + const devVersion = await getDevVersion(originalVersion); + + const confirm = await askDevVersion(devVersion); + if (!confirm) { + console.log(``); + return; + } + + const tasks = []; + + await setPackageVersionChanges(packages, devVersion); + + packages.forEach(package => { + common.prepareDevPackage(tasks, package, devVersion); + }); + common.publishPackages(tasks, packages, devVersion, DIST_TAG); + + const listr = new Listr(tasks); + await listr.run(); + + console.log(`\nionic ${devVersion} published!! 🎉\n`); + + } catch (err) { + console.log('\n', tc.red(err), '\n'); + process.exit(1); + } + + orgPkg.forEach(pkg => { + fs.writeFileSync(pkg.filePath, pkg.packageContent); + }); +} + +async function askDevVersion(devVersion) { + + const prompts = [ + { + type: 'confirm', + name: 'confirm', + value: true, + message: () => { + return `Publish the dev build ${tc.cyan(devVersion)}?`; + } + } + ]; + + const { confirm } = await inquirer.prompt(prompts); + return confirm; +} + +async function setPackageVersionChanges(packages, version) { + await Promise.all(packages.map(async package => { + if (package !== 'core') { + const pkg = common.readPkg(package); + common.updateDependency(pkg, '@ionic/core', version); + common.writePkg(package, pkg); + } + const projectRoot = common.projectPath(package); + await execa('npm', ['version', version], { cwd: projectRoot }); + })); +} + +async function getDevVersion(originalVersion) { + const { stdout: sha } = await execa('git', ['log', '-1', '--format=%H']); + const shortSha = sha.substring(0, 7); + const baseVersion = semver.inc(originalVersion, 'minor'); + + const d = new Date(); + + let timestamp = (d.getUTCFullYear() + ''); + timestamp += ('0' + (d.getUTCMonth() + 1)).slice(-2); + timestamp += ('0' + d.getUTCDate()).slice(-2); + timestamp += ('0' + d.getUTCHours()).slice(-2); + timestamp += ('0' + d.getUTCMinutes()).slice(-2); + + return `${baseVersion}-${DIST_TAG}.${timestamp}.${shortSha}`; +} + +main(); diff --git a/.scripts/release.js b/.scripts/release.js index dd750aa6f1..a67c752492 100644 --- a/.scripts/release.js +++ b/.scripts/release.js @@ -24,7 +24,7 @@ async function main() { common.checkGit(tasks); // publish each package in NPM - publishPackages(tasks, common.packages, version); + common.publishPackages(tasks, common.packages, version); // push tag to git remote publishGit(tasks, version, changelog); @@ -40,36 +40,6 @@ async function main() { } -async function publishPackages(tasks, packages, version) { - // first verify version - packages.forEach(package => { - if (package === 'core') { - return; - } - - const pkg = common.readPkg(package); - tasks.push({ - title: `${pkg.name}: check version (must match: ${version})`, - task: () => { - if (version !== pkg.version) { - throw new Error(`${pkg.name} version ${pkg.version} must match ${version}`); - } - } - }); - }); - - // next publish - packages.forEach(package => { - const pkg = common.readPkg(package); - const projectRoot = common.projectPath(package); - - tasks.push({ - title: `${pkg.name}: publish ${pkg.version}`, - task: () => execa('npm', ['publish', '--tag', 'latest'], { cwd: projectRoot }) - }); - }); -} - function publishGit(tasks, version, changelog) { const tag = `v${version}`; diff --git a/package.json b/package.json index f52509bff0..0ae09a5ab4 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "private": true, "scripts": { "build": "node .scripts/build.js", + "release.dev": "node .scripts/release-dev.js", "release.prepare": "node .scripts/prepare.js", "release": "node .scripts/release.js", "changelog": "conventional-changelog -p angular -i ./CHANGELOG.md -k core -s"