Skip to content

Commit

Permalink
Use Circle CI API v2 to get artifacts job ID (facebook#15821)
Browse files Browse the repository at this point in the history
  • Loading branch information
Brian Vaughn authored Jun 4, 2019
1 parent 8d4fb13 commit 7fa5a71
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,23 @@

'use strict';

const http = require('request-promise-json');
const {exec} = require('child-process-promise');
const {existsSync, readdirSync} = require('fs');
const {readJsonSync} = require('fs-extra');
const {join} = require('path');
const {logPromise} = require('../utils');
const {getArtifactsList, logPromise} = require('../utils');
const theme = require('../theme');

const run = async ({build, cwd}) => {
// https://circleci.com/docs/2.0/artifacts/#downloading-all-artifacts-for-a-build-on-circleci
const metadataURL = `https://circleci.com/api/v1.1/project/github/facebook/react/${build}/artifacts?circle-token=${
process.env.CIRCLE_CI_API_TOKEN
}`;
const metadata = await http.get(metadataURL, true);
const nodeModulesArtifact = metadata.find(
const artifacts = await getArtifactsList(build);
const nodeModulesArtifact = artifacts.find(
entry => entry.path === 'home/circleci/project/node_modules.tgz'
);

if (!nodeModulesArtifact) {
console.log(
theme`{error The specified build number does not contain any build artifacts}\n\n` +
'To get the correct build number from Circle CI, open the following URL:\n' +
theme`{link https://circleci.com/gh/facebook/react/${build}}\n\n` +
'Select the "commit" Workflow at the top of the page, then select the "process_artifacts" job.'
theme`{error The specified build (${build}) does not contain any build artifacts.}`
);

process.exit(1);
}

Expand Down
14 changes: 4 additions & 10 deletions scripts/release/publish-commands/download-error-codes-from-ci.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@

'use strict';

const http = require('request-promise-json');
const {exec} = require('child-process-promise');
const {readJsonSync} = require('fs-extra');
const {logPromise} = require('../utils');
const {getArtifactsList, logPromise} = require('../utils');
const theme = require('../theme');

const run = async ({cwd, tags}) => {
Expand All @@ -23,19 +22,14 @@ const run = async ({cwd, tags}) => {
// If this release was created on Circle CI, grab the updated error codes from there.
// Else the user will have to manually regenerate them.
if (environment === 'ci') {
// https://circleci.com/docs/2.0/artifacts/#downloading-all-artifacts-for-a-build-on-circleci
// eslint-disable-next-line max-len
const metadataURL = `https://circleci.com/api/v1.1/project/github/facebook/react/${buildNumber}/artifacts?circle-token=${
process.env.CIRCLE_CI_API_TOKEN
}`;
const metadata = await http.get(metadataURL, true);
const artifacts = await getArtifactsList(buildNumber);

// Each container stores an "error-codes" artifact, unfortunately.
// We want to use the one that also ran `yarn build` since it may have modifications.
const {node_index} = metadata.find(
const {node_index} = artifacts.find(
entry => entry.path === 'home/circleci/project/node_modules.tgz'
);
const {url} = metadata.find(
const {url} = artifacts.find(
entry =>
entry.node_index === node_index &&
entry.path === 'home/circleci/project/scripts/error-codes/codes.json'
Expand Down
39 changes: 38 additions & 1 deletion scripts/release/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const {createPatch} = require('diff');
const {hashElement} = require('folder-hash');
const {readdirSync, readFileSync, statSync, writeFileSync} = require('fs');
const {readJson, writeJson} = require('fs-extra');
const http = require('request-promise-json');
const logUpdate = require('log-update');
const {join} = require('path');
const createLogger = require('progress-estimator');
Expand All @@ -31,6 +32,42 @@ const execRead = async (command, options) => {
return stdout.trim();
};

const getArtifactsList = async buildID => {
const buildMetadataURL = `https://circleci.com/api/v1.1/project/github/facebook/react/${buildID}?circle-token=${
process.env.CIRCLE_CI_API_TOKEN
}`;
const buildMetadata = await http.get(buildMetadataURL, true);
if (!buildMetadata.workflows || !buildMetadata.workflows.workflow_id) {
console.log(
theme`{error Could not find workflow info for build ${buildID}.}`
);
process.exit(1);
}

const workflowID = buildMetadata.workflows.workflow_id;
const workflowMetadataURL = `https://circleci.com/api/v2/workflow/${workflowID}/jobs?circle-token=${
process.env.CIRCLE_CI_API_TOKEN
}`;
const workflowMetadata = await http.get(workflowMetadataURL, true);

const job = workflowMetadata.jobs.find(
({name}) => name === 'process_artifacts'
);
if (!job || !job.job_number) {
console.log(
theme`{error Could not find "process_artifacts" job for workflow ${workflowID}.}`
);
process.exit(1);
}

const jobArtifactsURL = `https://circleci.com/api/v1.1/project/github/facebook/react/${
job.job_number
}/artifacts?circle-token=${process.env.CIRCLE_CI_API_TOKEN}`;
const jobArtifacts = await http.get(jobArtifactsURL, true);

return jobArtifacts;
};

const getBuildInfo = async () => {
const cwd = join(__dirname, '..', '..');

Expand Down Expand Up @@ -87,7 +124,6 @@ const handleError = error => {
const stack = error.stack.replace(error.message, '');

console.log(theme`{error ${message}}\n\n{path ${stack}}`);

process.exit(1);
};

Expand Down Expand Up @@ -185,6 +221,7 @@ const updateVersionsForCanary = async (cwd, reactVersion, version) => {
module.exports = {
confirm,
execRead,
getArtifactsList,
getBuildInfo,
getChecksumForCurrentRevision,
getPublicPackages,
Expand Down

0 comments on commit 7fa5a71

Please sign in to comment.