@percy/cli-build 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build.js +8 -0
- package/dist/finalize.js +35 -0
- package/dist/index.js +3 -0
- package/dist/wait.js +137 -0
- package/package.json +4 -4
package/dist/build.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import command from '@percy/cli-command';
|
|
2
|
+
import finalize from './finalize.js';
|
|
3
|
+
import wait from './wait.js';
|
|
4
|
+
export const build = command('build', {
|
|
5
|
+
description: 'Finalize and wait on Percy builds',
|
|
6
|
+
commands: [finalize, wait]
|
|
7
|
+
});
|
|
8
|
+
export default build;
|
package/dist/finalize.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import command from '@percy/cli-command';
|
|
2
|
+
export const finalize = command('finalize', {
|
|
3
|
+
description: 'Finalize parallel Percy builds',
|
|
4
|
+
percy: true
|
|
5
|
+
}, async ({
|
|
6
|
+
env,
|
|
7
|
+
percy,
|
|
8
|
+
log,
|
|
9
|
+
exit
|
|
10
|
+
}) => {
|
|
11
|
+
if (!percy) exit(0, 'Percy is disabled'); // automatically set parallel total to -1
|
|
12
|
+
|
|
13
|
+
env.PERCY_PARALLEL_TOTAL || (env.PERCY_PARALLEL_TOTAL = '-1'); // ensure that this command is not used for other parallel totals
|
|
14
|
+
|
|
15
|
+
if (env.PERCY_PARALLEL_TOTAL !== '-1') {
|
|
16
|
+
log.error('This command should only be used with PERCY_PARALLEL_TOTAL=-1');
|
|
17
|
+
log.error(`Current value is "${env.PERCY_PARALLEL_TOTAL}"`);
|
|
18
|
+
exit(1);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
log.info('Finalizing parallel build...'); // rely on the parallel nonce to cause the API to return the current running build for the nonce
|
|
22
|
+
|
|
23
|
+
let {
|
|
24
|
+
data: build
|
|
25
|
+
} = await percy.client.createBuild();
|
|
26
|
+
await percy.client.finalizeBuild(build.id, {
|
|
27
|
+
all: true
|
|
28
|
+
});
|
|
29
|
+
let {
|
|
30
|
+
'build-number': number,
|
|
31
|
+
'web-url': url
|
|
32
|
+
} = build.attributes;
|
|
33
|
+
log.info(`Finalized build #${number}: ${url}`);
|
|
34
|
+
});
|
|
35
|
+
export default finalize;
|
package/dist/index.js
ADDED
package/dist/wait.js
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import command from '@percy/cli-command';
|
|
2
|
+
export const wait = command('wait', {
|
|
3
|
+
description: 'Wait for a build to be finished',
|
|
4
|
+
flags: [{
|
|
5
|
+
name: 'build',
|
|
6
|
+
description: 'Build ID',
|
|
7
|
+
exclusive: ['project', 'commit'],
|
|
8
|
+
type: 'id',
|
|
9
|
+
short: 'b'
|
|
10
|
+
}, {
|
|
11
|
+
name: 'project',
|
|
12
|
+
description: 'Build project slug, requires \'--commit\'',
|
|
13
|
+
requires: ['commit'],
|
|
14
|
+
type: 'slug',
|
|
15
|
+
short: 'p'
|
|
16
|
+
}, {
|
|
17
|
+
name: 'commit',
|
|
18
|
+
description: 'Build commit sha, requires \'--project\'',
|
|
19
|
+
requires: ['project'],
|
|
20
|
+
type: 'sha',
|
|
21
|
+
short: 'c'
|
|
22
|
+
}, {
|
|
23
|
+
name: 'timeout',
|
|
24
|
+
description: 'Timeout before exiting without updates, defaults to 10 minutes',
|
|
25
|
+
type: 'ms',
|
|
26
|
+
parse: Number,
|
|
27
|
+
short: 't'
|
|
28
|
+
}, {
|
|
29
|
+
name: 'interval',
|
|
30
|
+
description: 'Interval at which to poll for updates, defaults to 1 second',
|
|
31
|
+
type: 'ms',
|
|
32
|
+
parse: Number,
|
|
33
|
+
short: 'i'
|
|
34
|
+
}, {
|
|
35
|
+
name: 'fail-on-changes',
|
|
36
|
+
description: 'Exit with an error when diffs are found',
|
|
37
|
+
short: 'f'
|
|
38
|
+
}],
|
|
39
|
+
examples: ['$0 --build 2222222', '$0 --project org/project --commit HEAD'],
|
|
40
|
+
percy: true
|
|
41
|
+
}, async function* ({
|
|
42
|
+
flags,
|
|
43
|
+
percy,
|
|
44
|
+
log,
|
|
45
|
+
exit
|
|
46
|
+
}) {
|
|
47
|
+
if (!percy) exit(0, 'Percy is disabled'); // do not wait directly on the promise as to not block the event loop
|
|
48
|
+
|
|
49
|
+
let waiting = percy.client.waitForBuild(flags, build => {
|
|
50
|
+
logProgress(build, log);
|
|
51
|
+
if (isFailing(build, flags)) exit(1);
|
|
52
|
+
}); // wait between event loops to allow process termination
|
|
53
|
+
|
|
54
|
+
let handleDone = () => waiting.done = true;
|
|
55
|
+
|
|
56
|
+
waiting.then(handleDone, handleDone);
|
|
57
|
+
|
|
58
|
+
while (!waiting.done) {
|
|
59
|
+
yield new Promise(r => setImmediate(r));
|
|
60
|
+
} // bubble errors
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
yield waiting;
|
|
64
|
+
}); // Log build progress
|
|
65
|
+
|
|
66
|
+
function logProgress({
|
|
67
|
+
attributes: {
|
|
68
|
+
state,
|
|
69
|
+
'web-url': url,
|
|
70
|
+
'build-number': number,
|
|
71
|
+
'failure-reason': failReason,
|
|
72
|
+
'failure-details': failDetails,
|
|
73
|
+
'total-snapshots': count,
|
|
74
|
+
'total-comparisons': total,
|
|
75
|
+
'total-comparisons-diff': diffs,
|
|
76
|
+
'total-comparisons-finished': finished
|
|
77
|
+
}
|
|
78
|
+
}, log) {
|
|
79
|
+
switch (state) {
|
|
80
|
+
case 'pending':
|
|
81
|
+
return log.progress('Recieving snapshots...');
|
|
82
|
+
|
|
83
|
+
case 'processing':
|
|
84
|
+
return log.progress(`Processing ${count} snapshots - ` + (finished === total ? 'finishing up...' : `${finished} of ${total} comparisons finished...`));
|
|
85
|
+
|
|
86
|
+
case 'finished':
|
|
87
|
+
log.info(`Build #${number} finished! ${url}`);
|
|
88
|
+
return log.info(`Found ${diffs} changes`);
|
|
89
|
+
|
|
90
|
+
case 'failed':
|
|
91
|
+
log.error(`Build #${number} failed! ${url}`);
|
|
92
|
+
return log.error(failureMessage(failReason, failDetails));
|
|
93
|
+
|
|
94
|
+
default:
|
|
95
|
+
return log.error(`Build #${number} is ${state}. ${url}`);
|
|
96
|
+
}
|
|
97
|
+
} // Create failure messages
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
function failureMessage(type, {
|
|
101
|
+
missing_parallel_builds: missingParallel,
|
|
102
|
+
parallel_builds_received: parallelCount,
|
|
103
|
+
parallel_builds_expected: parallelTotal
|
|
104
|
+
} = {}) {
|
|
105
|
+
switch (type) {
|
|
106
|
+
case 'render_timeout':
|
|
107
|
+
return 'Some snapshots in this build took too long ' + 'to render even after multiple retries.';
|
|
108
|
+
|
|
109
|
+
case 'no_snapshots':
|
|
110
|
+
return 'No snapshots were uploaded to this build.';
|
|
111
|
+
|
|
112
|
+
case 'missing_finalize':
|
|
113
|
+
return 'Failed to correctly finalize.';
|
|
114
|
+
|
|
115
|
+
case 'missing_resources':
|
|
116
|
+
return missingParallel ? `Only ${parallelCount} of ${parallelTotal} parallel builds were received.` : 'Some build or snapshot resources failed to correctly upload.';
|
|
117
|
+
|
|
118
|
+
default:
|
|
119
|
+
return `Error: ${type}`;
|
|
120
|
+
}
|
|
121
|
+
} // Return true or false if a build is considered failing or not
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
function isFailing({
|
|
125
|
+
attributes: {
|
|
126
|
+
state,
|
|
127
|
+
'total-comparisons-diff': diffs
|
|
128
|
+
}
|
|
129
|
+
}, {
|
|
130
|
+
failOnChanges
|
|
131
|
+
}) {
|
|
132
|
+
// not pending and not processing
|
|
133
|
+
return state !== 'pending' && state !== 'processing' && ( // not finished or finished with diffs
|
|
134
|
+
state !== 'finished' || failOnChanges && !!diffs);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export default wait;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@percy/cli-build",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"node": ">=14"
|
|
15
15
|
},
|
|
16
16
|
"files": [
|
|
17
|
-
"
|
|
17
|
+
"dist"
|
|
18
18
|
],
|
|
19
19
|
"main": "./dist/index.js",
|
|
20
20
|
"type": "module",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
]
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@percy/cli-command": "1.0.
|
|
35
|
+
"@percy/cli-command": "1.0.1"
|
|
36
36
|
},
|
|
37
|
-
"gitHead": "
|
|
37
|
+
"gitHead": "38917e6027299d6cd86008e2ccd005d90bbf89c0"
|
|
38
38
|
}
|