@samitouri / QOS-React-2 / commits / c64d6d21be

Implement CI job that publishes prereleases (#20732)

PR #20728 added a command to initiate a prerelease using CI, but it left the publish job unimplemented. This fills in the publish job. Uses an npm automation token for authorization, which bypasses the need for a one-time password. The token is configured via CircleCI's environment variable panel. Currently, it will always publish the head of the main branch. If the head has already been published, it will exit gracefully. It does not yet support publishing arbitrary commits, though we could easily add that. I don't know how important that use case is, because for PR branches, you can use CodeSandbox CI instead. Or as a last resort, run the publish script locally. Always publishing from main is nice because it further incentivizes us to keep main in a releasable state. It also takes the guesswork out of publishing a prerelease that's in a broken state: as long as we don't merge broken PRs, we're fine.

Andrew Clark committed Feb 3, 2021 at 22:57 UTC c64d6d21be19e179bd6a2d659fa78180051b577f
3 files changed +38 -13
.circleci/config.yml
+21 -11
@@ -358,16 +358,22 @@ jobs:
358 type: string
359 release_channel:
360 type: string
361 + dist_tag:
362 + type: string
363 docker: *docker
364 environment: *environment
365 steps:
366 - checkout
367 - run: yarn workspaces info | head -n -1 > workspace_info.txt
368 - *restore_node_modules
367 - # TODO: This doesn't actually publish anything yet. Just logs the inputs.
368 - - run: |
369 - echo "<< parameters.commit_sha >>"
370 - echo "<< parameters.release_channel >>"
369 + - run:
370 + name: Run publish script
371 + command: |
372 + git fetch origin master
373 + cd ./scripts/release && yarn && cd ../../
374 + scripts/release/prepare-release-from-ci.js --skipTests -r << parameters.release_channel >> --commit=<< parameters.commit_sha >>
375 + cp ./scripts/release/ci-npmrc ~/.npmrc
376 + scripts/release/publish.js --ci --tags << parameters.dist_tag >>
377
378 workflows:
379 version: 2
@@ -516,12 +522,16 @@ workflows:
522 jobs:
523 - setup
524 - publish_prerelease:
525 + name: Publish to Next channel
526 requires:
527 - setup
521 - matrix:
522 - parameters:
523 - commit_sha:
524 - - << pipeline.parameters.prerelease_commit_sha >>
525 - release_channel:
526 - - stable
527 - - experimental
528 + commit_sha: << pipeline.parameters.prerelease_commit_sha >>
529 + release_channel: stable
530 + dist_tag: next
531 + - publish_prerelease:
532 + name: Publish to Experimental channel
533 + requires:
534 + - setup
535 + commit_sha: << pipeline.parameters.prerelease_commit_sha >>
536 + release_channel: experimental
537 + dist_tag: experimental
scripts/release/ci-npmrc new
+1
@@ -0,0 +1 @@
1 +//registry.npmjs.org/:_authToken=${NPM_TOKEN}
scripts/release/publish.js
+16 -2
@@ -53,9 +53,23 @@ const run = async () => {
53 const packageNames = params.packages;
54
55 if (params.ci) {
56 + let failed = false;
57 for (let i = 0; i < packageNames.length; i++) {
57 - const packageName = packageNames[i];
58 - await publishToNPM(params, packageName, null);
58 + try {
59 + const packageName = packageNames[i];
60 + await publishToNPM(params, packageName, null);
61 + } catch (error) {
62 + failed = true;
63 + console.error(error.message);
64 + console.log();
65 + console.log(
66 + theme.error`Publish failed. Will attempt to publish remaining packages.`
67 + );
68 + }
69 + }
70 + if (failed) {
71 + console.log(theme.error`One or more packages failed to publish.`);
72 + process.exit(1);
73 }
74 } else {
75 clear();