149 lines
4.0 KiB
JavaScript
149 lines
4.0 KiB
JavaScript
'use strict';
|
|
|
|
const fetch = require('node-fetch');
|
|
|
|
const {logPromise} = require('./utils');
|
|
const theme = require('./theme');
|
|
|
|
const CIRCLE_TOKEN = process.env.CIRCLE_CI_API_TOKEN;
|
|
|
|
if (!CIRCLE_TOKEN) {
|
|
console.error(
|
|
theme.error(
|
|
'Missing required environment variable: CIRCLE_CI_API_TOKEN\n' +
|
|
'Grab it here: https://app.circleci.com/settings/user/tokens'
|
|
)
|
|
);
|
|
process.exit(1);
|
|
}
|
|
|
|
function sleep(ms) {
|
|
return new Promise(resolve => {
|
|
setTimeout(() => resolve(), ms);
|
|
});
|
|
}
|
|
|
|
async function getPublishWorkflowID(pipelineID) {
|
|
// Since we just created the pipeline in a POST request, the server may 404.
|
|
// Try a few times before giving up.
|
|
for (let i = 0; i < 20; i++) {
|
|
const pipelineWorkflowsResponse = await fetch(
|
|
`https://circleci.com/api/v2/pipeline/${pipelineID}/workflow`
|
|
);
|
|
if (pipelineWorkflowsResponse.ok) {
|
|
const pipelineWorkflowsJSON = await pipelineWorkflowsResponse.json();
|
|
const workflows = pipelineWorkflowsJSON.items;
|
|
if (workflows.length !== 0) {
|
|
return workflows[0].id;
|
|
}
|
|
}
|
|
// CircleCI server may be stale. Wait a sec and try again.
|
|
await sleep(1000);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
async function pollUntilWorkflowFinishes(workflowID) {
|
|
while (true) {
|
|
const workflowResponse = await fetch(
|
|
`https://circleci.com/api/v2/workflow/${workflowID}`
|
|
);
|
|
const workflow = await workflowResponse.json();
|
|
switch (workflow.status) {
|
|
case 'running':
|
|
// Workflow still running. Wait a bit then check again.
|
|
await sleep(2000);
|
|
continue;
|
|
case 'success':
|
|
// Publish succeeded! Continue.
|
|
return;
|
|
case 'not_run':
|
|
case 'failed':
|
|
case 'error':
|
|
case 'failing':
|
|
case 'on_hold':
|
|
case 'canceled':
|
|
case 'unauthorized':
|
|
default:
|
|
console.error(
|
|
theme.error(
|
|
`Failed to publish. Workflow exited with status: ${workflow.status}`
|
|
)
|
|
);
|
|
console.error(
|
|
`Visit https://app.circleci.com/pipelines/workflows/${workflowID} for details.`
|
|
);
|
|
process.exit(1);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
async function main() {
|
|
const headCommitResponse = await fetch(
|
|
'https://api.github.com/repos/facebook/react/commits/main'
|
|
);
|
|
const headCommitJSON = await headCommitResponse.json();
|
|
const headCommitSha = headCommitJSON.sha;
|
|
|
|
const pipelineResponse = await fetch(
|
|
'https://circleci.com/api/v2/project/github/facebook/react/pipeline',
|
|
{
|
|
method: 'post',
|
|
body: JSON.stringify({
|
|
parameters: {
|
|
prerelease_commit_sha: headCommitSha,
|
|
},
|
|
}),
|
|
headers: {
|
|
'Circle-Token': CIRCLE_TOKEN,
|
|
'Content-Type': 'application/json',
|
|
},
|
|
}
|
|
);
|
|
|
|
if (!pipelineResponse.ok) {
|
|
console.error(
|
|
theme.error(
|
|
`Failed to access CircleCI. Responded with status: ${pipelineResponse.status}`
|
|
)
|
|
);
|
|
process.exit(1);
|
|
}
|
|
|
|
const pipelineJSON = await pipelineResponse.json();
|
|
const pipelineID = pipelineJSON.id;
|
|
|
|
const workflowID = await logPromise(
|
|
getPublishWorkflowID(pipelineID),
|
|
theme`{header Creating CI workflow}`,
|
|
2 * 1000 // Estimated time: 2 seconds,
|
|
);
|
|
|
|
if (workflowID === null) {
|
|
console.warn(
|
|
theme.yellow(
|
|
'Created a CI pipeline to publish the packages, but the script timed ' +
|
|
"out when requesting the associated workflow ID. It's still " +
|
|
'possible the workflow was created.\n\n' +
|
|
'Visit ' +
|
|
'https://app.circleci.com/pipelines/github/facebook/react?branch=main ' +
|
|
'for a list of the latest workflows.'
|
|
)
|
|
);
|
|
process.exit(1);
|
|
}
|
|
|
|
await logPromise(
|
|
pollUntilWorkflowFinishes(workflowID),
|
|
theme`{header Publishing in CI workflow}: https://app.circleci.com/pipelines/workflows/${workflowID}`,
|
|
2 * 60 * 1000 // Estimated time: 2 minutes,
|
|
);
|
|
}
|
|
|
|
main().catch(error => {
|
|
console.error(theme.error('Failed to trigger publish workflow.'));
|
|
console.error(error.message);
|
|
process.exit(1);
|
|
});
|