Skip to content

fix(repo): use Promise.allSettled for release downstream dispatches#8102

Open
jacekradko wants to merge 5 commits intomainfrom
jacek/release-dispatch-allsettled
Open

fix(repo): use Promise.allSettled for release downstream dispatches#8102
jacekradko wants to merge 5 commits intomainfrom
jacek/release-dispatch-allsettled

Conversation

@jacekradko
Copy link
Member

@jacekradko jacekradko commented Mar 17, 2026

Summary

Improves the reliability of downstream repo notifications in the release workflow. Addresses two failure modes:

1. Isolated dispatch failures shouldn't block other repos

  • Replaces Promise.all with Promise.allSettled so a failure dispatching to one repo (e.g. clerk-docs 403) doesn't prevent notifications to the others (sdk-infra-workers, dashboard)
  • Failed dispatches are logged with the target repo/workflow for easy triage
  • Steps use continue-on-error: true + core.setFailed() so failures are visible (red step) but don't block the rest of the release job

2. Recovery when changesets fails after publishing

  • Adds a recovery step that runs when changesets/action fails (e.g. git push --follow-tags error)
  • When the changesets step fails, published is never set to true, so downstream notifications are silently skipped — and on retry, nothing is left to publish
  • The recovery step checks npm to see if packages were actually published, and if so, dispatches to downstream repos
  • Only runs for stable releases (skips pre-releases and pre-mode)

Context: Failed run — a 403 on clerk-docs caused Promise.all to reject. The 6.1.0 stable release on March 9 hit the second issue where changesets failed after publishing to npm.

Supersedes #8027.

Test plan

  • Verify workflow YAML is valid
  • Promise.allSettled: dispatches to unaffected repos succeed even when one dispatch fails
  • Failed dispatches surface as step errors with target repo name (visible in Actions UI)
  • Recovery step is a no-op when changesets succeeds (condition not met)
  • Recovery step is a no-op when changesets fails before publishing (npm check returns not found)
  • Recovery step dispatches when changesets fails after publishing either package

Summary by CodeRabbit

  • Chores
    • More resilient release process: downstream triggers now tolerate partial failures, aggregate and report errors, and surface a consolidated failure status.
    • Automatic recovery attempts: failed downstream publishes may trigger retry notifications to recover interrupted releases, with safeguards for pre-release/canary flows.
    • Improved traceability: consolidated targeting and propagation of source-commit info for downstream releases; added a minimal changeset placeholder.

@vercel
Copy link

vercel bot commented Mar 17, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Ready Ready Preview, Comment Mar 17, 2026 7:25pm

Request Review

@changeset-bot
Copy link

changeset-bot bot commented Mar 17, 2026

🦋 Changeset detected

Latest commit: 32f1622

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 17, 2026

📝 Walkthrough

Walkthrough

The release workflow (.github/workflows/release.yml) was updated: two trigger steps now set continue-on-error: true; individual createWorkflowDispatch calls were replaced with targets arrays; downstream dispatches use Promise.allSettled() with collection of settled results, per-dispatch error logging, and the step is marked failed if any dispatches fail. A Recovery downstream notification was added to attempt re-dispatch when the publishing path failed (with pre-release/pre-mode safeguards). sourceCommit was added to inputs for sdk-infra-workers, and accounts dispatches are included conditionally when nextjsVersion contains canary. A new empty changeset .changeset/release-dispatch-allsettled.md was added.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and clearly summarizes the main change: switching from Promise.all to Promise.allSettled for release downstream dispatches, which is the core objective of the PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

📝 Coding Plan
  • Generate coding plan for human review comments

Comment @coderabbitai help to get the list of available commands and usage tips.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 17, 2026

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@8102

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@8102

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@8102

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@8102

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@8102

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@8102

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@8102

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@8102

@clerk/express

npm i https://pkg.pr.new/@clerk/express@8102

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@8102

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@8102

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@8102

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@8102

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@8102

@clerk/react

npm i https://pkg.pr.new/@clerk/react@8102

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@8102

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@8102

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@8102

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@8102

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@8102

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@8102

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@8102

commit: 32f1622

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/release.yml:
- Line 116: The failure log only prints r.reason; update the failed.forEach
callback to include dispatch target identifiers so failures can be triaged
(e.g., include repo/owner, workflow name and ref/inputs). Locate the
failed.forEach(...) expression and augment its core.error message to concatenate
r.reason with fields from the dispatch request object such as r.request
(owner/repo), r.request?.workflow or r.request?.name, and r.request?.ref (or
similar properties used when building the dispatch) so each logged line contains
both the error and the target identifiers.
- Line 77: The workflow currently uses continue-on-error: true which masks job
failures while steps still call core.setFailed; remove the broad
continue-on-error: true and instead change the dispatch-failure handling to call
core.warning(...) rather than core.setFailed(...) so the dispatch error is
treated as a warning while other step failures still fail the job; update the
occurrences of core.setFailed in the dispatch logic to core.warning and delete
the continue-on-error: true entries to preserve proper failure visibility.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: a3f7ef17-b4e2-4a74-b48d-9ab85e8c7015

📥 Commits

Reviewing files that changed from the base of the PR and between 206d2b7 and 71cb67b.

📒 Files selected for processing (1)
  • .github/workflows/release.yml

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
.github/workflows/release.yml (1)

77-105: ⚠️ Potential issue | 🟠 Major

Still avoid pairing continue-on-error with core.setFailed() here.

At Line [77] and Line [194], continue-on-error: true masks any exception thrown anywhere in these github-script steps, not just rejected dispatches. Because Line [104] and Line [225] still call core.setFailed(), the step also emits failure/error annotations instead of the warning-only behavior this PR is trying to introduce. Handle expected dispatch failures with core.warning(...) and let unexpected script bugs fail the job normally.

Suggested fix
-        continue-on-error: true
@@
-              if (failures.length) {
-                failures.forEach(f => core.error(`Dispatch to ${f.target.repo}/${f.target.workflow_id} failed: ${f.reason?.message ?? f.reason}`));
-                core.setFailed(`${failures.length} downstream dispatch(es) failed`);
-              }
+              if (failures.length) {
+                failures.forEach(f => core.warning(`Dispatch to ${f.target.repo}/${f.target.workflow_id} failed: ${f.reason?.message ?? f.reason}`));
+                core.warning(`${failures.length} downstream dispatch(es) failed`);
+              }

Apply the same change to both trigger steps.

GitHub Actions documentation: if a step uses `continue-on-error: true` and the script calls `core.setFailed()`, what are the step's `outcome` and `conclusion`, and does `core.warning()` better match warning-only UI annotations?

Also applies to: 194-225

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/release.yml around lines 77 - 105, The github-script steps
currently set continue-on-error: true but still call core.setFailed(...) when
dispatches fail, which turns expected-dispatch failures into hard failures;
change the handler that processes the failures array so it uses
core.warning(...) (including the same descriptive message and the failure count)
instead of core.setFailed(...), leaving unexpected exceptions unhandled so they
will fail the step normally; apply this same replacement in both github-script
steps that build the targets/results/failures logic (the code that constructs
targets, runs Promise.allSettled, inspects results into failures, and currently
calls core.setFailed).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In @.github/workflows/release.yml:
- Around line 77-105: The github-script steps currently set continue-on-error:
true but still call core.setFailed(...) when dispatches fail, which turns
expected-dispatch failures into hard failures; change the handler that processes
the failures array so it uses core.warning(...) (including the same descriptive
message and the failure count) instead of core.setFailed(...), leaving
unexpected exceptions unhandled so they will fail the step normally; apply this
same replacement in both github-script steps that build the
targets/results/failures logic (the code that constructs targets, runs
Promise.allSettled, inspects results into failures, and currently calls
core.setFailed).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6518ee06-f6cf-4be2-a767-d699fccfb653

📥 Commits

Reviewing files that changed from the base of the PR and between 71cb67b and 91bf9f6.

📒 Files selected for processing (1)
  • .github/workflows/release.yml

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/release.yml:
- Around line 147-153: The catch in isPublished currently swallows all errors;
change it to capture the error (e.g., catch (err)) and log it (for example using
console.warn or core.warning) with context including the package name and
version before returning false so transient registry or network errors are
visible; update the isPublished function around the execSync call to include the
caught error in the log message.
- Around line 171-175: The duplicated targets array (variable name targets
containing entries with repo:'sdk-infra-workers', repo:'dashboard',
repo:'clerk-docs' and workflow_id keys like 'update-pkg-versions.yml',
'prepare-nextjs-sdk-update.yml', 'typedoc.yml') should be deduplicated: extract
it into a single shared source (e.g., a JSON/YAML file or a reusable composite
action) and have this workflow load/reference that single definition, or at
minimum add a clear inline comment in both places pointing to the other location
to prevent drift; update the release.yml to reference the shared definition (or
include the linking comment) and ensure inputs (clerkjsVersion, clerkUiVersion,
version: nextjsVersion) remain intact.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: cac0549a-5564-41d0-927e-43ff7d996b4e

📥 Commits

Reviewing files that changed from the base of the PR and between 9bfaa80 and 32f1622.

📒 Files selected for processing (1)
  • .github/workflows/release.yml

Comment on lines +147 to +153
function isPublished(name, version) {
try {
return execSync(`npm view ${name}@${version} version`, { encoding: 'utf8' }).trim() === version;
} catch {
return false;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider logging suppressed errors in isPublished for debuggability.

The catch block silently returns false for any error. While this is reasonable for "check if published" semantics, transient npm registry errors would be indistinguishable from "package not published," potentially skipping recovery when it should have run.

♻️ Proposed improvement for debuggability
             function isPublished(name, version) {
               try {
                 return execSync(`npm view ${name}@${version} version`, { encoding: 'utf8' }).trim() === version;
-              } catch {
+              } catch (e) {
+                console.log(`npm view ${name}@${version} failed: ${e.message}`);
                 return false;
               }
             }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function isPublished(name, version) {
try {
return execSync(`npm view ${name}@${version} version`, { encoding: 'utf8' }).trim() === version;
} catch {
return false;
}
}
function isPublished(name, version) {
try {
return execSync(`npm view ${name}@${version} version`, { encoding: 'utf8' }).trim() === version;
} catch (e) {
console.log(`npm view ${name}@${version} failed: ${e.message}`);
return false;
}
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/release.yml around lines 147 - 153, The catch in
isPublished currently swallows all errors; change it to capture the error (e.g.,
catch (err)) and log it (for example using console.warn or core.warning) with
context including the package name and version before returning false so
transient registry or network errors are visible; update the isPublished
function around the execSync call to include the caught error in the log
message.

Comment on lines +171 to +175
const targets = [
{ repo: 'sdk-infra-workers', workflow_id: 'update-pkg-versions.yml', inputs: { clerkjsVersion, clerkUiVersion } },
{ repo: 'dashboard', workflow_id: 'prepare-nextjs-sdk-update.yml', inputs: { version: nextjsVersion } },
{ repo: 'clerk-docs', workflow_id: 'typedoc.yml' },
];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Extract shared targets array to reduce duplication.

The targets array is duplicated verbatim from lines 91-95. If a downstream repository is added or removed, both locations must be updated, risking drift.

Consider extracting the targets definition to a shared location (e.g., a JSON file or a reusable composite action) or at minimum, add a comment linking the two locations to alert future maintainers.

♻️ Alternative: inline comment to link the two locations
+            // NOTE: Keep in sync with targets array in "Trigger workflows on related repos" step above
             const targets = [
               { repo: 'sdk-infra-workers', workflow_id: 'update-pkg-versions.yml', inputs: { clerkjsVersion, clerkUiVersion } },
               { repo: 'dashboard', workflow_id: 'prepare-nextjs-sdk-update.yml', inputs: { version: nextjsVersion } },
               { repo: 'clerk-docs', workflow_id: 'typedoc.yml' },
             ];
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const targets = [
{ repo: 'sdk-infra-workers', workflow_id: 'update-pkg-versions.yml', inputs: { clerkjsVersion, clerkUiVersion } },
{ repo: 'dashboard', workflow_id: 'prepare-nextjs-sdk-update.yml', inputs: { version: nextjsVersion } },
{ repo: 'clerk-docs', workflow_id: 'typedoc.yml' },
];
// NOTE: Keep in sync with targets array in "Trigger workflows on related repos" step above
const targets = [
{ repo: 'sdk-infra-workers', workflow_id: 'update-pkg-versions.yml', inputs: { clerkjsVersion, clerkUiVersion } },
{ repo: 'dashboard', workflow_id: 'prepare-nextjs-sdk-update.yml', inputs: { version: nextjsVersion } },
{ repo: 'clerk-docs', workflow_id: 'typedoc.yml' },
];
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/release.yml around lines 171 - 175, The duplicated targets
array (variable name targets containing entries with repo:'sdk-infra-workers',
repo:'dashboard', repo:'clerk-docs' and workflow_id keys like
'update-pkg-versions.yml', 'prepare-nextjs-sdk-update.yml', 'typedoc.yml')
should be deduplicated: extract it into a single shared source (e.g., a
JSON/YAML file or a reusable composite action) and have this workflow
load/reference that single definition, or at minimum add a clear inline comment
in both places pointing to the other location to prevent drift; update the
release.yml to reference the shared definition (or include the linking comment)
and ensure inputs (clerkjsVersion, clerkUiVersion, version: nextjsVersion)
remain intact.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant