chore(deploy): update deploy scripts

This commit is contained in:
Adam Bradley
2018-03-28 15:35:31 -05:00
parent a5d2a33016
commit f304480dfc
10 changed files with 202 additions and 3488 deletions

View File

@ -6,37 +6,27 @@ const semver = require('semver');
const rootDir = path.join(__dirname, '../'); const rootDir = path.join(__dirname, '../');
const packages = [
'core',
'angular'
];
function readPkg(project) { function readPkg(package) {
const packageJsonPath = path.join(rootDir, project, 'package.json'); const packageJsonPath = path.join(rootDir, package, 'package.json');
return JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')); return JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
} }
function rootPath() {
return rootDir;
}
function projectPath(project) { function projectPath(project) {
return path.join(rootDir, project); return path.join(rootDir, project);
} }
async function checkGit() { function checkGit(tasks) {
const listr = new Listr([ tasks.push(
{
title: 'Check npm version',
skip: () => isVersionLower('6.0.0', process.version),
task: () => execa.stdout('npm', ['version', '--json']).then(json => {
const versions = JSON.parse(json);
if (!satisfies(versions.npm, '>=2.15.8 <3.0.0 || >=3.10.1')) {
throw new Error(`npm@${versions.npm} has known issues publishing when running Node.js 6. Please upgrade npm or downgrade Node and publish again. https://github.com/npm/npm/issues/5082`);
}
})
},
{ {
title: 'Check current branch', title: 'Check current branch',
task: () => execa.stdout('git', ['symbolic-ref', '--short', 'HEAD']).then(branch => { task: () => execa.stdout('git', ['symbolic-ref', '--short', 'HEAD']).then(branch => {
if (branch !== 'master' && branch !== 'core') { if (branch !== 'master') {
throw new Error('Not on `master` or `core` branch'); throw new Error(`Not on "master" branch`);
} }
}) })
}, },
@ -44,7 +34,7 @@ async function checkGit() {
title: 'Check local working tree', title: 'Check local working tree',
task: () => execa.stdout('git', ['status', '--porcelain']).then(status => { task: () => execa.stdout('git', ['status', '--porcelain']).then(status => {
if (status !== '') { if (status !== '') {
throw new Error('Unclean working tree. Commit or stash changes first.'); throw new Error(`Unclean working tree. Commit or stash changes first.`);
} }
}) })
}, },
@ -52,31 +42,21 @@ async function checkGit() {
title: 'Check remote history', title: 'Check remote history',
task: () => execa.stdout('git', ['rev-list', '--count', '--left-only', '@{u}...HEAD']).then(result => { task: () => execa.stdout('git', ['rev-list', '--count', '--left-only', '@{u}...HEAD']).then(result => {
if (result !== '0') { if (result !== '0') {
throw new Error('Remote history differs. Please pull changes.'); throw new Error(`Remote history differs. Please pull changes.`);
} }
}) })
} }
]); );
await listr.run();
} }
const satisfies = (version, range) => semver.satisfies(version, range);
const isValidVersion = input => Boolean(semver.valid(input)); const isValidVersion = input => Boolean(semver.valid(input));
const isVersionLower = (oldVersion, newVersion) => {
if (!isValidVersion(newVersion)) {
throw new Error('Version should be a valid semver version.');
}
return semver.lt(newVersion, oldVersion);
};
module.exports = { module.exports = {
isValidVersion, isValidVersion,
readPkg, readPkg,
rootPath, rootDir,
projectPath, projectPath,
checkGit, checkGit,
packages
}; };

View File

@ -14,64 +14,24 @@ const path = require('path');
async function main() { async function main() {
try { try {
await common.checkGit();
const version = await askVersion(); const version = await askVersion();
await checkTagVersion(version);
// compiler and verify projects (read-only) // compile and verify packages
await prepareProject('core', version); await preparePackages(common.packages, version);
await prepareProject('angular', version, ['@ionic/core']);
// writes start here console.log(`\nionic ${version} prepared 🤖\n`);
// update package.json of each project console.log(`Next steps:`);
await updateVersion('core', version); console.log(` Verify CHANGELOG.md`);
await updateVersion('angular', version); console.log(` git commit -m "${version}"`);
console.log(` git push`);
console.log(` npm run deploy\n`);
// generate changelog
await generateChangeLog(version);
process.exit(0);
} catch(err) { } catch(err) {
console.log('\n', chalk.red(err), '\n'); console.log('\n', chalk.red(err), '\n');
process.exit(1); process.exit(1);
} }
} }
async function checkTagVersion(version) {
const listr = new Listr([
{
title: 'Check git tag existence',
task: () => execa('git', ['fetch'])
.then(() => {
return execa.stdout('npm', ['config', 'get', 'tag-version-prefix']);
})
.then(
output => {
tagPrefix = output;
},
() => {}
)
.then(() => execa.stdout('git', ['rev-parse', '--quiet', '--verify', `refs/tags/${tagPrefix}${version}`]))
.then(
output => {
if (output) {
throw new Error(`Git tag \`${tagPrefix}${version}\` already exists.`);
}
},
err => {
// Command fails with code 1 and no output if the tag does not exist, even though `--quiet` is provided
// https://github.com/sindresorhus/np/pull/73#discussion_r72385685
if (err.stdout !== '' || err.stderr !== '') {
throw err;
}
}
)
},
]);
await listr.run();
}
async function askVersion() { async function askVersion() {
const pkg = common.readPkg('core'); const pkg = common.readPkg('core');
@ -126,84 +86,155 @@ async function askVersion() {
return version; return version;
} }
async function prepareProject(project, version, dependencies) {
const projectRoot = common.projectPath(project);
const pkg = common.readPkg(project);
const oldVersion = pkg.version;
console.log(`\nPrepare to publish a new version of ${chalk.bold.magenta(pkg.name)} ${chalk.dim(`(${oldVersion}) => (${version})`)}\n`); async function preparePackages(packages, version) {
// execution order matters
const tasks = [];
const tasks = [ // check git is nice and clean local and remote
common.checkGit(tasks);
// test we're good with git
validateGit(tasks, version);
// add all the prepare scripts
// run all these tasks before updating package.json version
packages.forEach(package => {
preparePackage(tasks, package, version);
});
// add update package.json of each project
packages.forEach(package => {
updatePackageVersion(tasks, package, version);
});
// generate changelog
generateChangeLog(tasks);
const listr = new Listr(tasks, { showSubtasks: false });
await listr.run();
}
function validateGit(tasks, version) {
tasks.push(
{ {
title: 'Validate version', title: `Validate git tag ${chalk.dim(`(v${version})`)}`,
task: () => execa('git', ['fetch'])
.then(() => {
return execa.stdout('npm', ['config', 'get', 'tag-version-prefix']);
})
.then(
output => {
tagPrefix = output;
},
() => {}
)
.then(() => execa.stdout('git', ['rev-parse', '--quiet', '--verify', `refs/tags/${tagPrefix}${version}`]))
.then(
output => {
if (output) {
throw new Error(`Git tag \`${tagPrefix}${version}\` already exists.`);
}
},
err => {
// Command fails with code 1 and no output if the tag does not exist, even though `--quiet` is provided
// https://github.com/sindresorhus/np/pull/73#discussion_r72385685
if (err.stdout !== '' || err.stderr !== '') {
throw err;
}
}
)
},
);
}
function preparePackage(tasks, package, version) {
const projectRoot = common.projectPath(package);
const pkg = common.readPkg(package);
tasks.push(
{
title: `${pkg.name}: validate new version`,
task: () => { task: () => {
if (!isVersionGreater(pkg.version, version)) { if (!isVersionGreater(pkg.version, version)) {
throw new Error(`New version \`${newVersion}\` should be higher than current version \`${pkg.version}\``); throw new Error(`New version \`${version}\` should be higher than current version \`${pkg.version}\``);
} }
} }
}, },
{ {
title: 'Cleanup', title: `${pkg.name}: install npm dependencies`,
task: () => fs.remove(path.join(projectRoot, 'node_modules')) task: async () => {
}, await fs.remove(path.join(projectRoot, 'node_modules'))
{ await execa('npm', ['install'], { cwd: projectRoot });
title: 'Install npm dependencies', }
task: () => execa('npm', ['install'], { cwd: projectRoot }), }
}]; );
if (dependencies && dependencies.length > 0) { if (package !== 'core') {
tasks.push( tasks.push(
{ {
title: 'Linking local dependencies', title: `${pkg.name}: npm link @ionic/core`,
task: () => { task: () => execa('npm', ['link', '@ionic/core'], { cwd: projectRoot })
return new Listr(dependencies.map(dep => ({
title: dep,
task: () => execa('npm', ['link', dep], { cwd: projectRoot }),
})));
}
} }
); );
} }
tasks.push( tasks.push(
{ {
title: 'Run lint', title: `${pkg.name}: lint`,
task: () => execa('npm', ['run', 'lint'], { cwd: projectRoot }) task: () => execa('npm', ['run', 'lint'], { cwd: projectRoot })
}, },
{ {
title: 'Build ' + pkg.name, title: `${pkg.name}: build`,
task: () => execa('npm', ['run', 'build'], { cwd: projectRoot }) task: () => execa('npm', ['run', 'build'], { cwd: projectRoot })
}, },
{ {
title: 'Run tests', title: `${pkg.name}: test`,
task: () => execa('npm', ['test'], { cwd: projectRoot }) task: () => execa('npm', ['test'], { cwd: projectRoot })
},
{
title: 'Linking',
task: () => execa('npm', ['link'], { cwd: projectRoot })
} }
); );
const listr = new Listr(tasks, { showSubtasks: false }); if (package === 'core') {
await listr.run(); tasks.push(
{
title: `${pkg.name}: npm link`,
task: () => execa('npm', ['link'], { cwd: projectRoot })
}
);
}
} }
async function updateVersion(project, version) {
const projectRoot = common.projectPath(project); function updatePackageVersion(tasks, package, version) {
const listr = new Listr([{ const projectRoot = common.projectPath(package);
title: `Updating ${project}/package.json version ${chalk.dim(`(${version})`)}`, const pkg = common.readPkg(package);
task: () => execa('npm', ['version', version], { cwd: projectRoot }),
}]); tasks.push(
await listr.run(); {
title: `${pkg.name}: update package.json ${chalk.dim(`(${version})`)}`,
task: async () => {
await execa('npm', ['version', version], { cwd: projectRoot });
const pkgLock = path.join(projectRoot, 'package-lock.json');
const pkgLockData = JSON.parse(fs.readFileSync(pkgLock, 'utf-8'));
pkgLockData.version = version;
fs.writeFileSync(pkgLock, JSON.stringify(pkgLockData));
}
}
);
} }
async function generateChangeLog() {
const rootDir = common.rootPath(); async function generateChangeLog(tasks) {
const listr = new Listr([{ tasks.push(
title: 'Generate CHANGELOG', {
task: () => execa('npm', ['run', 'changelog'], { cwd: rootDir }), title: `Generate CHANGELOG.md`,
}]); task: () => execa('npm', ['run', 'changelog'], { cwd: common.rootDir }),
await listr.run(); }
);
} }

View File

@ -12,17 +12,10 @@ async function main() {
try { try {
const {version} = common.readPkg('core'); const {version} = common.readPkg('core');
// repo must be clean // publish each package in NPM
await common.checkGit(); await publishPackages(common.packages, version);
// publish each project in NPM console.log(`\nionic ${version} published!! 🎉\n`);
await publishProjects(['core', 'angular'], version);
// push commits and tags to git remote
await publishGit(version);
console.log(`\n${version} published!! 🎉\n`);
process.exit(0);
} catch (err) { } catch (err) {
console.log('\n', chalk.red(err), '\n'); console.log('\n', chalk.red(err), '\n');
@ -30,42 +23,63 @@ async function main() {
} }
} }
async function publishProjects(projects, newVersion) {
async function publishPackages(packages, version) {
const tasks = []; const tasks = [];
projects.forEach((project) => {
const {name, version} = common.readPkg(project); // repo must be clean
tasks.push({ common.checkGit(tasks);
title: `Checking version of name (must match: ${version})`,
task: () => { // first verify version
if(newVersion !== version) { packages.forEach(package => {
throw new Error('version does not match'); 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}`);
}
} }
} }
}); );
}); });
projects.forEach((project) => { // next publish
const projectRoot = common.projectPath(project); packages.forEach(package => {
tasks.push({ const pkg = common.readPkg(package);
title: `Publish (latest) ${project} (v${newVersion})`,
task: () => execa('npm', ['publish', '--tag', 'latest'], { cwd: projectRoot }) tasks.push(
}); {
title: `${pkg.name}: publish ${pkg.version}`,
task: () =>execa('npm', ['publish', '--tag', 'latest'], { cwd: projectRoot })
}
);
}); });
// push commits and tags to git remote
publishGit(version);
const listr = new Listr(tasks); const listr = new Listr(tasks);
await listr.run(); await listr.run();
} }
async function publishGit(version) {
const rootDir = common.rootPath(); function publishGit(tasks, version) {
const listr = new Listr([{ tasks.push(
title: 'Tagging the latest commit', {
task: () => execa('git', ['tag', `v${version}`], { cwd: rootDir }) title: 'Tagging the latest commit',
}, task: () => execa('git', ['tag', `v${version}`], { cwd: common.rootDir })
{ },
title: 'Pushing to Github', {
task: () => execa('git', ['push', '--follow-tags'], { cwd: rootDir }) title: 'Pushing to Github',
}]); task: () => execa('git', ['push', '--follow-tags'], { cwd: common.rootDir })
await listr.run(); }
);
} }
main(); main();

3300
angular/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{ {
"name": "@ionic/angular", "name": "@ionic/angular",
"version": "0.1.4", "version": "0.1.5-4",
"description": "Angular specific wrappers for @ionic/core", "description": "Angular specific wrappers for @ionic/core",
"keywords": [ "keywords": [
"ionic", "ionic",
@ -25,8 +25,10 @@
"clean": "node scripts/clean.js", "clean": "node scripts/clean.js",
"clean-generated": "node ./scripts/clean-generated.js", "clean-generated": "node ./scripts/clean-generated.js",
"compile": "./node_modules/.bin/ngc", "compile": "./node_modules/.bin/ngc",
"ionic-core": "stencil build --dev", "ionic-core": "node ../core/node_modules/.bin/stencil build",
"ionic-core-dev": "node ../core/node_modules/.bin/stencil build --dev",
"lint": "tslint --project .", "lint": "tslint --project .",
"test": "echo 'angular no tests yet'",
"tsc": "tsc -p ." "tsc": "tsc -p ."
}, },
"main": "./dist/index.js", "main": "./dist/index.js",
@ -45,8 +47,7 @@
"@angular/platform-browser": "latest", "@angular/platform-browser": "latest",
"@angular/platform-browser-dynamic": "latest", "@angular/platform-browser-dynamic": "latest",
"@angular/router": "latest", "@angular/router": "latest",
"@ionic/core": "^0.1.4", "@ionic/core": "latest",
"@stencil/core": "^0.7.9",
"chalk": "^2.3.2", "chalk": "^2.3.2",
"execa": "^0.9.0", "execa": "^0.9.0",
"fs-extra": "^5.0.0", "fs-extra": "^5.0.0",

View File

@ -230,14 +230,6 @@
"resolved": "https://registry.npmjs.org/@ionic/angular/-/angular-0.0.2-29.tgz", "resolved": "https://registry.npmjs.org/@ionic/angular/-/angular-0.0.2-29.tgz",
"integrity": "sha512-6HkJ+IZAy1o+EKjw1hBn+/CzkhHolCMXnUBxjHBCdNduCkeAiijFVCmok5lYbTjCX0xNI/rBtJmkFKrotBmWLQ==" "integrity": "sha512-6HkJ+IZAy1o+EKjw1hBn+/CzkhHolCMXnUBxjHBCdNduCkeAiijFVCmok5lYbTjCX0xNI/rBtJmkFKrotBmWLQ=="
}, },
"@ionic/core": {
"version": "0.1.5-4",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-0.1.5-4.tgz",
"integrity": "sha512-dXaxgiWtiZc8pQzu/ia05OAqyr6QVwZFxOyKVhW/kIlzsTFfvNaxaPLnjG05YHqVYnRAhLd8ll00fgBYf95vWg==",
"requires": {
"ionicons": "4.0.0-18"
}
},
"@ngtools/json-schema": { "@ngtools/json-schema": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/@ngtools/json-schema/-/json-schema-1.2.0.tgz", "resolved": "https://registry.npmjs.org/@ngtools/json-schema/-/json-schema-1.2.0.tgz",
@ -4810,11 +4802,6 @@
"integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=",
"dev": true "dev": true
}, },
"ionicons": {
"version": "4.0.0-18",
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-4.0.0-18.tgz",
"integrity": "sha512-nPijotkyDVy1tX6IBuo9/uLnWLtvwYUxX5YGcJJ0meyx6XwUrc+9irDF/xXkVnnUrw9cHbGoJv2Hs0l65wMWLQ=="
},
"ip": { "ip": {
"version": "1.1.5", "version": "1.1.5",
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",

View File

@ -22,7 +22,6 @@
"@angular/platform-browser-dynamic": "latest", "@angular/platform-browser-dynamic": "latest",
"@angular/router": "latest", "@angular/router": "latest",
"@ionic/angular": "next", "@ionic/angular": "next",
"@ionic/core": "next",
"body-parser": "^1.18.2", "body-parser": "^1.18.2",
"core-js": "^2.4.1", "core-js": "^2.4.1",
"express": "^4.16.2", "express": "^4.16.2",

View File

@ -24,7 +24,7 @@
"ionicons": "4.0.0-18" "ionicons": "4.0.0-18"
}, },
"devDependencies": { "devDependencies": {
"@stencil/core": "^0.7.9", "@stencil/core": "0.7.9",
"@stencil/dev-server": "latest", "@stencil/dev-server": "latest",
"@stencil/postcss": "0.0.2", "@stencil/postcss": "0.0.2",
"@stencil/sass": "0.0.3", "@stencil/sass": "0.0.3",
@ -57,7 +57,8 @@
"devapp": "sd concurrent \"stencil build --dev --watch --docs\" \"stencil-dev-server --broadcast\"", "devapp": "sd concurrent \"stencil build --dev --watch --docs\" \"stencil-dev-server --broadcast\"",
"e2e": "node ./scripts/e2e", "e2e": "node ./scripts/e2e",
"e2e-debug": "node --inspect --debug-brk ./scripts/e2e", "e2e-debug": "node --inspect --debug-brk ./scripts/e2e",
"lint": "npm run tslint & npm run sass-lint", "lint": "npm run tslint && npm run sass-lint",
"prerelease": "npm run validate && np prerelease --yolo --any-branch --tag next",
"sass-lint": "sass-lint -v -q", "sass-lint": "sass-lint -v -q",
"set.version": "node scripts/set-version.js", "set.version": "node scripts/set-version.js",
"snapshot": "node ./scripts/e2e --snapshot", "snapshot": "node ./scripts/e2e --snapshot",
@ -67,11 +68,10 @@
"theme-builder": "sd concurrent \"npm run theme-app-build\" \"stencil build --dev --watch\" \"stencil-dev-server\" \"npm run theme-server\" ", "theme-builder": "sd concurrent \"npm run theme-app-build\" \"stencil build --dev --watch\" \"stencil-dev-server\" \"npm run theme-server\" ",
"theme-builder:dev": "sd concurrent \"npm run theme-app-build -- --watch\" \"stencil build --dev --watch\" \"stencil-dev-server\" \"npm run theme-server\" ", "theme-builder:dev": "sd concurrent \"npm run theme-app-build -- --watch\" \"stencil build --dev --watch\" \"stencil-dev-server\" \"npm run theme-server\" ",
"theme-server": "node scripts/theme-builder/server.js", "theme-server": "node scripts/theme-builder/server.js",
"tsc": "./node_modules/.bin/tsc -p .",
"tslint": "tslint --project .", "tslint": "tslint --project .",
"tslint-fix": "tslint --project . --fix", "tslint-fix": "tslint --project . --fix",
"prerelease": "npm run validate && np prerelease --yolo --any-branch --tag next", "validate": "npm i && npm run lint && npm run test && npm run build"
"validate": "npm i && npm run lint && npm run test && npm run build",
"tsc": "./node_modules/.bin/tsc -p ."
}, },
"author": "Ionic Team", "author": "Ionic Team",
"license": "MIT", "license": "MIT",

View File

@ -6,7 +6,7 @@
"scripts": { "scripts": {
"prepare.deploy": "node .scripts/prepare.js", "prepare.deploy": "node .scripts/prepare.js",
"deploy": "node .scripts/publish.js", "deploy": "node .scripts/publish.js",
"changelog": "conventional-changelog -p angular -i core/CHANGELOG.md -k core -s" "changelog": "conventional-changelog -p angular -i ./CHANGELOG.md -k core -s"
}, },
"devDependencies": { "devDependencies": {
"chalk": "^2.3.2", "chalk": "^2.3.2",