forked from angular/angular-cli
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpublish.ts
132 lines (112 loc) · 3.68 KB
/
publish.ts
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
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
// tslint:disable:no-implicit-dependencies
import { logging, tags } from '@angular-devkit/core';
import { spawnSync } from 'child_process';
import * as semver from 'semver';
import { packages } from '../lib/packages';
import build from './build';
export interface PublishArgs {
tag?: string;
branchCheck?: boolean;
versionCheck?: boolean;
registry?: string;
}
function _exec(command: string, args: string[], opts: { cwd?: string }, logger: logging.Logger) {
if (process.platform.startsWith('win')) {
args.unshift('/c', command);
command = 'cmd.exe';
}
const { status, error, stderr, stdout } = spawnSync(command, args, { ...opts });
if (status != 0) {
logger.error(`Command failed: ${command} ${args.map(x => JSON.stringify(x)).join(', ')}`);
if (error) {
logger.error('Error: ' + (error ? error.message : 'undefined'));
} else {
logger.error(`STDERR:\n${stderr}`);
}
throw error;
} else {
return stdout.toString();
}
}
function _branchCheck(args: PublishArgs, logger: logging.Logger) {
logger.info('Checking branch...');
const ref = _exec('git', ['symbolic-ref', 'HEAD'], {}, logger);
const branch = ref.trim().replace(/^refs\/heads\//, '');
switch (branch) {
case 'master':
if (args.tag !== 'next') {
throw new Error(tags.oneLine`
Releasing from master requires a next tag. Use --branchCheck=false to skip this check.
`);
}
}
}
function _versionCheck(args: PublishArgs, logger: logging.Logger) {
logger.info('Checking version...');
// Find _any_ version that's beta or RC.
let betaOrRc = false;
let version = '';
Object.keys(packages).forEach((name: string) => {
// If there's _ANY_ prerelease information, it's on.
if (semver.prerelease(packages[name].version)) {
betaOrRc = true;
version = packages[name].version;
}
});
if (betaOrRc && args.tag !== 'next') {
throw new Error(tags.oneLine`
Releasing version ${JSON.stringify(version)} requires a next tag.
Use --versionCheck=false to skip this check.
`);
}
Object.keys(packages).forEach((name: string) => {
if (packages[name].version.indexOf('+') >= 0) {
throw new Error(tags.oneLine`
Releasing a version with a + in it means that the latest commit is not tagged properly.
Version found: ${JSON.stringify(packages[name].version)}
`);
}
});
}
export default async function (args: PublishArgs, logger: logging.Logger) {
if (args.branchCheck === undefined || args.branchCheck === true) {
_branchCheck(args, logger);
}
if (args.versionCheck === undefined || args.versionCheck === true) {
_versionCheck(args, logger);
}
logger.info('Building...');
await build({}, logger.createChild('build'));
return Object.keys(packages).reduce((acc: Promise<void>, name: string) => {
const pkg = packages[name];
if (pkg.packageJson['private']) {
logger.debug(`${name} (private)`);
return acc;
}
return acc
.then(() => {
logger.info(name);
const publishArgs = ['publish'];
if (args.tag) {
publishArgs.push('--tag', args.tag);
}
if (args.registry) {
publishArgs.push('--registry', args.registry);
}
return _exec('npm', publishArgs, {
cwd: pkg.dist,
}, logger);
})
.then((stdout: string) => {
logger.info(stdout);
});
}, Promise.resolve())
.then(() => logger.info('done'), (err: Error) => logger.fatal(err.message));
}