Use Circle CI API v2 to get artifacts job ID (#15821)
Brian Vaughn committed
Jun 4, 2019 at 13:28 UTC
7fa5a716e3c0f77ec479768ebe3fa8d09a00af9b
3 files changed
+46
-24
scripts/release/prepare-canary-commands/download-build-artifacts.js
+4
-13
@@ -2,32 +2,23 @@
2
3
'use strict';
4
5
-const http = require('request-promise-json');
5
const {exec} = require('child-process-promise');
6
const {existsSync, readdirSync} = require('fs');
7
const {readJsonSync} = require('fs-extra');
8
const {join} = require('path');
10
-const {logPromise} = require('../utils');
9
+const {getArtifactsList, logPromise} = require('../utils');
10
const theme = require('../theme');
11
12
const run = async ({build, cwd}) => {
14
- // https://circleci.com/docs/2.0/artifacts/#downloading-all-artifacts-for-a-build-on-circleci
15
- const metadataURL = `https://circleci.com/api/v1.1/project/github/facebook/react/${build}/artifacts?circle-token=${
16
- process.env.CIRCLE_CI_API_TOKEN
17
- }`;
18
- const metadata = await http.get(metadataURL, true);
19
- const nodeModulesArtifact = metadata.find(
13
+ const artifacts = await getArtifactsList(build);
14
+ const nodeModulesArtifact = artifacts.find(
15
entry => entry.path === 'home/circleci/project/node_modules.tgz'
16
);
17
18
if (!nodeModulesArtifact) {
19
console.log(
25
- theme`{error The specified build number does not contain any build artifacts}\n\n` +
26
- 'To get the correct build number from Circle CI, open the following URL:\n' +
27
- theme`{link https://circleci.com/gh/facebook/react/${build}}\n\n` +
28
- 'Select the "commit" Workflow at the top of the page, then select the "process_artifacts" job.'
20
+ theme`{error The specified build (${build}) does not contain any build artifacts.}`
21
);
30
-
22
process.exit(1);
23
}
24
scripts/release/publish-commands/download-error-codes-from-ci.js
+4
-10
@@ -2,10 +2,9 @@
2
3
'use strict';
4
5
-const http = require('request-promise-json');
5
const {exec} = require('child-process-promise');
6
const {readJsonSync} = require('fs-extra');
8
-const {logPromise} = require('../utils');
7
+const {getArtifactsList, logPromise} = require('../utils');
8
const theme = require('../theme');
9
10
const run = async ({cwd, tags}) => {
@@ -23,19 +22,14 @@ const run = async ({cwd, tags}) => {
22
// If this release was created on Circle CI, grab the updated error codes from there.
23
// Else the user will have to manually regenerate them.
24
if (environment === 'ci') {
26
- // https://circleci.com/docs/2.0/artifacts/#downloading-all-artifacts-for-a-build-on-circleci
27
- // eslint-disable-next-line max-len
28
- const metadataURL = `https://circleci.com/api/v1.1/project/github/facebook/react/${buildNumber}/artifacts?circle-token=${
29
- process.env.CIRCLE_CI_API_TOKEN
30
- }`;
31
- const metadata = await http.get(metadataURL, true);
25
+ const artifacts = await getArtifactsList(buildNumber);
26
27
// Each container stores an "error-codes" artifact, unfortunately.
28
// We want to use the one that also ran `yarn build` since it may have modifications.
35
- const {node_index} = metadata.find(
29
+ const {node_index} = artifacts.find(
30
entry => entry.path === 'home/circleci/project/node_modules.tgz'
31
);
38
- const {url} = metadata.find(
32
+ const {url} = artifacts.find(
33
entry =>
34
entry.node_index === node_index &&
35
entry.path === 'home/circleci/project/scripts/error-codes/codes.json'
scripts/release/utils.js
+38
-1
@@ -5,6 +5,7 @@ const {createPatch} = require('diff');
5
const {hashElement} = require('folder-hash');
6
const {readdirSync, readFileSync, statSync, writeFileSync} = require('fs');
7
const {readJson, writeJson} = require('fs-extra');
8
+const http = require('request-promise-json');
9
const logUpdate = require('log-update');
10
const {join} = require('path');
11
const createLogger = require('progress-estimator');
@@ -31,6 +32,42 @@ const execRead = async (command, options) => {
32
return stdout.trim();
33
};
34
35
+const getArtifactsList = async buildID => {
36
+ const buildMetadataURL = `https://circleci.com/api/v1.1/project/github/facebook/react/${buildID}?circle-token=${
37
+ process.env.CIRCLE_CI_API_TOKEN
38
+ }`;
39
+ const buildMetadata = await http.get(buildMetadataURL, true);
40
+ if (!buildMetadata.workflows || !buildMetadata.workflows.workflow_id) {
41
+ console.log(
42
+ theme`{error Could not find workflow info for build ${buildID}.}`
43
+ );
44
+ process.exit(1);
45
+ }
46
+
47
+ const workflowID = buildMetadata.workflows.workflow_id;
48
+ const workflowMetadataURL = `https://circleci.com/api/v2/workflow/${workflowID}/jobs?circle-token=${
49
+ process.env.CIRCLE_CI_API_TOKEN
50
+ }`;
51
+ const workflowMetadata = await http.get(workflowMetadataURL, true);
52
+
53
+ const job = workflowMetadata.jobs.find(
54
+ ({name}) => name === 'process_artifacts'
55
+ );
56
+ if (!job || !job.job_number) {
57
+ console.log(
58
+ theme`{error Could not find "process_artifacts" job for workflow ${workflowID}.}`
59
+ );
60
+ process.exit(1);
61
+ }
62
+
63
+ const jobArtifactsURL = `https://circleci.com/api/v1.1/project/github/facebook/react/${
64
+ job.job_number
65
+ }/artifacts?circle-token=${process.env.CIRCLE_CI_API_TOKEN}`;
66
+ const jobArtifacts = await http.get(jobArtifactsURL, true);
67
+
68
+ return jobArtifacts;
69
+};
70
+
71
const getBuildInfo = async () => {
72
const cwd = join(__dirname, '..', '..');
73
@@ -87,7 +124,6 @@ const handleError = error => {
124
const stack = error.stack.replace(error.message, '');
125
126
console.log(theme`{error ${message}}\n\n{path ${stack}}`);
90
-
127
process.exit(1);
128
};
129
@@ -185,6 +221,7 @@ const updateVersionsForCanary = async (cwd, reactVersion, version) => {
221
module.exports = {
222
confirm,
223
execRead,
224
+ getArtifactsList,
225
getBuildInfo,
226
getChecksumForCurrentRevision,
227
getPublicPackages,