-
Notifications
You must be signed in to change notification settings - Fork 70
/
main.ts
executable file
·144 lines (126 loc) · 4.67 KB
/
main.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
133
134
135
136
137
138
139
140
141
142
143
144
import Listr from 'listr';
import { v4 as uuid } from 'uuid';
import readPkgUp from 'read-pkg-up';
import GraphQLClient from './io/GraphQLClient';
import HTTPClient from './io/HTTPClient';
import checkForUpdates from './lib/checkForUpdates';
import checkPackageJson from './lib/checkPackageJson';
import getEnv from './lib/getEnv';
import getOptions from './lib/getOptions';
import { createLogger } from './lib/log';
import NonTTYRenderer from './lib/NonTTYRenderer';
import parseArgs from './lib/parseArgs';
import { exitCodes, setExitCode } from './lib/setExitCode';
import { rewriteErrorMessage } from './lib/utils';
import { writeChromaticDiagnostics } from './lib/writeChromaticDiagnostics';
import getTasks from './tasks';
import { Context } from './types';
import fatalError from './ui/messages/errors/fatalError';
import fetchError from './ui/messages/errors/fetchError';
import graphqlError from './ui/messages/errors/graphqlError';
import invalidPackageJson from './ui/messages/errors/invalidPackageJson';
import missingStories from './ui/messages/errors/missingStories';
import noPackageJson from './ui/messages/errors/noPackageJson';
import runtimeError from './ui/messages/errors/runtimeError';
import taskError from './ui/messages/errors/taskError';
import intro from './ui/messages/info/intro';
import { endActivity } from './ui/components/activity';
export async function main(argv: string[]) {
const sessionId: string = uuid();
const env = getEnv();
const log = createLogger(sessionId, env);
const pkgInfo = await readPkgUp({ cwd: process.cwd() });
if (!pkgInfo) {
log.error(noPackageJson());
process.exit(253);
}
const { path: packagePath, packageJson } = pkgInfo;
if (typeof packageJson !== 'object' || typeof packageJson.scripts !== 'object') {
log.error(invalidPackageJson(packagePath));
process.exit(252);
}
// Warning: chromaui/action directly invokes runAll, so if new properties or arguments are added
// here, they must also be added to the GitHub Action.
const ctx: Partial<Context> = {
env,
log,
sessionId,
packageJson,
packagePath,
...parseArgs(argv),
};
await runAll(ctx);
log.info('');
process.exit(ctx.exitCode);
}
export async function runAll(ctx) {
setExitCode(ctx, exitCodes.OK);
ctx.http = (ctx.http as HTTPClient) || new HTTPClient(ctx);
// Run these in parallel; neither should ever reject
await Promise.all([runBuild(ctx), checkForUpdates(ctx)]);
if (ctx.exitCode === 0 || ctx.exitCode === 1) {
await checkPackageJson(ctx);
}
if (ctx.flags.diagnostics) {
await writeChromaticDiagnostics(ctx);
}
}
export async function runBuild(ctx: Context) {
ctx.log.info('');
ctx.log.info(intro(ctx));
try {
ctx.options = await getOptions(ctx);
} catch (e) {
ctx.log.info('');
ctx.log.error(fatalError(ctx, [e]));
setExitCode(ctx, exitCodes.INVALID_OPTIONS, true);
return;
}
try {
ctx.client = new GraphQLClient(ctx, `${ctx.env.CHROMATIC_INDEX_URL}/graphql`, {
headers: {
'x-chromatic-session-id': ctx.sessionId,
'x-chromatic-cli-version': ctx.pkg.version,
},
retries: 3,
});
try {
ctx.log.info('');
if (ctx.options.interactive) ctx.log.queue(); // queue up any log messages while Listr is running
const options = ctx.options.interactive ? {} : { renderer: NonTTYRenderer, log: ctx.log };
await new Listr(getTasks(ctx.options), options).run(ctx);
} catch (err) {
endActivity(ctx);
if (err.code === 'ECONNREFUSED' || err.name === 'StatusCodeError') {
setExitCode(ctx, exitCodes.FETCH_ERROR);
throw rewriteErrorMessage(err, fetchError(ctx, err));
}
if (err.name === 'GraphQLError') {
setExitCode(ctx, exitCodes.GRAPHQL_ERROR);
throw rewriteErrorMessage(err, graphqlError(ctx, err));
}
if (err.message.startsWith('Cannot run a build with no stories')) {
setExitCode(ctx, exitCodes.BUILD_NO_STORIES);
throw rewriteErrorMessage(err, missingStories(ctx));
}
throw rewriteErrorMessage(err, taskError(ctx, err));
} finally {
// Handle potential runtime errors from JSDOM
const { runtimeErrors, runtimeWarnings } = ctx;
if ((runtimeErrors && runtimeErrors.length) || (runtimeWarnings && runtimeWarnings.length)) {
ctx.log.info('');
ctx.log.error(runtimeError(ctx));
}
ctx.log.flush();
}
} catch (error) {
const errors = [].concat(error); // GraphQLClient might throw an array of errors
if (errors.length && !ctx.userError) {
ctx.log.info('');
ctx.log.error(fatalError(ctx, errors));
}
if (!ctx.exitCode) {
setExitCode(ctx, exitCodes.UNKNOWN_ERROR);
}
}
}