Skip to content

fix(release): publish-pipeline + Deploy-tab observability dependency#573

Merged
kaviththiranga merged 2 commits into
openchoreo:mainfrom
kaviththiranga:fix-npm-deps
May 20, 2026
Merged

fix(release): publish-pipeline + Deploy-tab observability dependency#573
kaviththiranga merged 2 commits into
openchoreo:mainfrom
kaviththiranga:fix-npm-deps

Conversation

@kaviththiranga
Copy link
Copy Markdown
Contributor

@kaviththiranga kaviththiranga commented May 20, 2026

Purpose

Two related bugs were blocking external installs of @openchoreo/*@1.1.0 per the docs:

  1. Publish pipeline leaked workspace:^ into tarballs. changeset publish shells out to
    npm publish for non-pnpm repos, and npm publish does not rewrite Yarn Berry's workspace:
    protocol. 13 of 17 published @openchoreo/*@1.1.0 packages contained literal workspace:^
    strings in dependencies. External yarn add @openchoreo/backstage-plugin@^1.1.0 failed with
    Workspace not found.

  2. Deploy tab hard-required the observability plugin. Following the install guide through
    Section 4 (Core) only, opening any component's Deploy tab threw NotImplementedError: No implementation available for apiRef{plugin.openchoreo-observability.service}. The hooks
    consuming observability already documented the intent that it be optional ("without requiring a
    package dependency") but used useApi() (throws) instead of useApiHolder().get() (returns
    undefined).

image

Goals

  • Get every @openchoreo/* package installable via yarn add against the published registry,
    with concrete version ranges in dependencies.
  • Make the Core Deploy tab render correctly without §5 Observability installed, matching the
    install guide's promise that "Section 4 is the only mandatory install."

Approach

Commit 1 — fix(release): publish with yarn npm publish to rewrite workspace deps

Replace changeset publish with yarn workspaces foreach --all --no-private --topological --verbose npm publish --tolerate-republish --access public --tag <latest|next>. Yarn Berry's
native publish rewrites workspace:^ to concrete versions at pack time, independent of
.npmrc:ignore-scripts=true. --tolerate-republish preserves the previous idempotent-on-retry
behaviour. changeset version (in prepare-next-version.yml) is untouched — only the publish
step moves.

Files changed:

  • package.jsonrelease:publish script
  • .github/workflows/release.yml — publish step + comment
  • README.md — release-procedure docs (incl. yarn pack-based local dry-run, since yarn npm publish --dry-run is not supported)

Verified locally: yarn workspaces foreach pack across all 22 public workspaces produced 22
clean tarballs with zero workspace: leaks. The @openchoreo/*@1.1.0 packages were
subsequently deleted from GitHub Packages and republished manually with the fixed command —
yarn add @openchoreo/backstage-plugin@^1.1.0 now succeeds end-to-end.

Commit 2 — fix(openchoreo): make observability dependency optional in Deploy tab

Switch both consumers of observabilityApiRef in @openchoreo/backstage-plugin from useApi()
to useApiHolder().get() and short-circuit each fetch when the API is undefined.

Files changed:

  • plugins/openchoreo/src/components/Environments/hooks/useIncidentsSummary.ts — returns an
    empty Map when observability isn't registered. PipelineCanvas already optional-chains
    incidentsSummaries.get(name)?.activeCount, so the Deploy tab now renders environment tiles
    cleanly without incident chips.
  • plugins/openchoreo/src/components/RuntimeLogs/OverviewCard/useLogsSummary.ts — sets
    observabilityDisabled: true. RuntimeHealthCard already routes that state to a friendly empty
    card (the same branch it uses when the backend reports observability is off cluster-side).

No UI changes — only the throw is gone.

User stories

  • As an external Backstage operator integrating OpenChoreo, I can yarn add @openchoreo/backstage-plugin@^1.1.0 and have it resolve.
  • As an operator who installs only the Core plugin set (no Observability), every Component's
    Deploy tab loads without runtime errors.

Release note

Fixed: @openchoreo/* packages no longer publish with workspace:^ strings in dependencies.
Fixed: Core Deploy tab no longer requires
@openchoreo/backstage-plugin-openchoreo-observability — installs of just the Core plugin set
work end-to-end.

Documentation

Release-procedure changes are in this PR's README.md diff. The OpenChoreo install guide is
being updated separately to flag Section 4's previously-implicit dependency on Section 5
(resolved by this PR) and other gaps surfaced during install testing.

Summary by CodeRabbit

  • Chores

    • Improved CI publish workflow to reliably publish workspace packages with consistent tags and idempotent republishing.
  • Documentation

    • Updated release docs with the new publish process, verification steps for dist-tags and concrete dependency versions, and updated local dry-run guidance.
  • Bug Fixes

    • UI now gracefully handles missing observability capabilities, avoiding errors and clearing related summaries/logs when the observability integration isn’t available.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 20, 2026

📝 Walkthrough

Walkthrough

CI publish was changed from conditional Changesets-based steps to always build all workspaces then publish each non-private workspace topologically via yarn workspaces foreach ... npm publish with --tolerate-republish, --access public, and a computed latest/next tag. README and package.json updated; two hooks now treat the observability API as optional and short-circuit when absent.

Changes

Release Publishing Strategy Refactor

Layer / File(s) Summary
Build step comment update
.github/workflows/release.yml
Clarify workflow must build all workspaces first so dist/ exists before packaging/publish.
Publish iteration and package.json script
.github/workflows/release.yml, package.json
Replace changeset/release publish branching with topological yarn workspaces foreach --no-private invoking npm publish --tolerate-republish --access public --tag TAG; update release:publish script to match.
Release docs and verification
README.md
Document Yarn-based publish flow, stable vs prerelease dist-tags, rationale to avoid workspace:^ leaks, extend verification for dist-tags and concrete dependency specs, clarify idempotency, and replace dry-run with offline pack+tarball checks.

Observability hooks: optional API handling

Layer / File(s) Summary
Incidents hook optional API
plugins/openchoreo/src/components/Environments/hooks/useIncidentsSummary.ts
Switch to useApiHolder().get(observabilityApiRef), comment on plugin-not-installed case, and early-return clearing summaries when API is unavailable.
Logs hook optional API
plugins/openchoreo/src/components/RuntimeLogs/OverviewCard/useLogsSummary.ts
Import useApiHolder, obtain observability API optionally, comment on plugin absence, and short-circuit fetchData to set observabilityDisabled and stop loading when API is missing.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • sameerajayasoma
  • stefinie123
  • LakshanSS

Poem

🐰 I hopped through workflows, scripts, and tags,
Built every workspace, then shredded the nags.
Published each package with tolerant cheer,
Observability optional — I draw no tear.
A tidy release, the rabbit says, "All clear!"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main changes: fixing the release publishing pipeline and addressing observability dependency issues in the Deploy tab.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The pull request description is comprehensive and well-structured, addressing all critical sections of the template including Purpose, Goals, Approach, User stories, Release note, and Documentation.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown

@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: 1

🧹 Nitpick comments (1)
.github/workflows/release.yml (1)

84-89: ⚡ Quick win

Guard latest dist-tag promotion with LATEST.

On Line [84]-Line [89], all stable tags publish with --tag latest. If an older stable tag is pushed, this can move latest backward. Use LATEST to gate latest promotion.

Suggested patch
-          TAG=latest
-          if [ "${IS_PRERELEASE}" = "true" ]; then
-            TAG=next
-          fi
+          if [ "${IS_PRERELEASE}" = "true" ]; then
+            TAG=next
+          elif [ "${LATEST}" = "true" ]; then
+            TAG=latest
+          else
+            echo "::error::Refusing to publish non-latest stable tag ${RELEASE_TAG} as latest"
+            exit 1
+          fi
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 84 - 89, The workflow currently
always sets TAG=latest unless IS_PRERELEASE is true, which can accidentally move
the latest dist-tag backwards; change the logic so TAG is only set to "latest"
when the new LATEST environment variable is explicitly "true" (keep TAG="next"
when IS_PRERELEASE is "true"), and only supply the --tag argument to the npm
publish invocation when TAG is set (i.e., gate passing --tag "${TAG}" behind a
conditional). Update the block that defines TAG and the yarn workspaces foreach
npm publish invocation to reference TAG, IS_PRERELEASE and LATEST accordingly so
latest promotion only happens when LATEST="true".
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@README.md`:
- Around line 523-524: Update the README sentence that currently claims "Yarn
Berry's `yarn npm publish` does not accept a `--dry-run` flag" to reflect the
correct behavior: change it to state that `yarn npm publish` supports a dry-run
via `-n, --dry-run` (or `--dry-run`) and can be used to preview what would be
published without uploading; optionally keep the `yarn pack` suggestion as an
alternative offline check but remove the definitive "does not accept" wording so
the README references the official CLI option (`yarn npm publish -n|--dry-run`)
instead.

---

Nitpick comments:
In @.github/workflows/release.yml:
- Around line 84-89: The workflow currently always sets TAG=latest unless
IS_PRERELEASE is true, which can accidentally move the latest dist-tag
backwards; change the logic so TAG is only set to "latest" when the new LATEST
environment variable is explicitly "true" (keep TAG="next" when IS_PRERELEASE is
"true"), and only supply the --tag argument to the npm publish invocation when
TAG is set (i.e., gate passing --tag "${TAG}" behind a conditional). Update the
block that defines TAG and the yarn workspaces foreach npm publish invocation to
reference TAG, IS_PRERELEASE and LATEST accordingly so latest promotion only
happens when LATEST="true".
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 385c60f9-8722-429d-88e3-6dd46ead7cc9

📥 Commits

Reviewing files that changed from the base of the PR and between e676ab7 and 7c89539.

📒 Files selected for processing (3)
  • .github/workflows/release.yml
  • README.md
  • package.json

Comment thread README.md
Comment on lines +523 to 524
Before the first real release, validate the publish path locally. Yarn Berry's `yarn npm publish` does not accept a `--dry-run` flag, so the equivalent offline check is `yarn pack` on every public workspace — `yarn pack` runs the same workspace-protocol rewriter that `yarn npm publish` does, just stopping before the upload:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Does Yarn 4 yarn npm publishsupport a--dry-run flag? Please return the official Yarn CLI docs page and option list.

💡 Result:

Yes. Yarn 4’s yarn npm publish command supports a dry-run option. Official Yarn CLI docs page: https://yarnpkg.com/cli/npm/publish [1] Option list for yarn npm publish (as shown on that page), including the dry-run flag: - -n,--dry-run — “Show what would be published without actually publishing” [1] Other options listed on the same page: - --access [1] - --tag [1] - --tolerate-republish [1] - --otp [1] - --provenance [1] - --json [1] So you can run: yarn npm publish --dry-run (or -n) to see what would be published without publishing to the registry. [1]

Citations:


Update documentation to reflect yarn npm publish --dry-run support.

Line 523 incorrectly states that Yarn Berry's yarn npm publish does not accept a --dry-run flag. The official Yarn CLI documentation confirms the command supports -n,--dry-run to show what would be published without actually publishing.

Suggested fix:

Patch
-Before the first real release, validate the publish path locally. Yarn Berry's `yarn npm publish` does not accept a `--dry-run` flag, so the equivalent offline check is `yarn pack` on every public workspace — `yarn pack` runs the same workspace-protocol rewriter that `yarn npm publish` does, just stopping before the upload:
+Before the first real release, validate the publish path locally. While `yarn npm publish` supports `--dry-run`, this repo uses an offline `yarn pack` check across all public workspaces so the same workspace-protocol rewrite path is validated without any registry interaction:
📝 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
Before the first real release, validate the publish path locally. Yarn Berry's `yarn npm publish` does not accept a `--dry-run` flag, so the equivalent offline check is `yarn pack` on every public workspace — `yarn pack` runs the same workspace-protocol rewriter that `yarn npm publish` does, just stopping before the upload:
Before the first real release, validate the publish path locally. While `yarn npm publish` supports `--dry-run`, this repo uses an offline `yarn pack` check across all public workspaces so the same workspace-protocol rewrite path is validated without any registry interaction:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 523 - 524, Update the README sentence that currently
claims "Yarn Berry's `yarn npm publish` does not accept a `--dry-run` flag" to
reflect the correct behavior: change it to state that `yarn npm publish`
supports a dry-run via `-n, --dry-run` (or `--dry-run`) and can be used to
preview what would be published without uploading; optionally keep the `yarn
pack` suggestion as an alternative offline check but remove the definitive "does
not accept" wording so the README references the official CLI option (`yarn npm
publish -n|--dry-run`) instead.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 20, 2026

Codecov Report

❌ Patch coverage is 0% with 8 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...mponents/Environments/hooks/useIncidentsSummary.ts 0.00% 3 Missing and 1 partial ⚠️
...ponents/RuntimeLogs/OverviewCard/useLogsSummary.ts 0.00% 3 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

The release workflow used `changeset publish`, which shells out to
`npm publish` for non-pnpm repos. `npm publish` does not understand
Yarn Berry's `workspace:^` protocol and serialised the literal string
into 13 of 17 @openchoreo/* tarballs at v1.1.0. External installs
fail with `Workspace not found` on first dependency resolution.

Replace the publish step with Yarn Berry's native
`yarn workspaces foreach --no-private --topological npm publish`,
which rewrites `workspace:^` to concrete versions at pack time —
independent of `.npmrc:ignore-scripts=true`, which would otherwise
also have blocked the prepack hook from running under npm publish.

`--tolerate-republish` preserves the idempotent-on-retry behaviour
of the previous setup. `changeset version` (in
prepare-next-version.yml) is unaffected — only the publish step
moves.

Verified by running `yarn workspaces foreach --no-private
--topological pack` across all 22 public workspaces and grepping
the resulting tarballs: every `@openchoreo/*` dep was rewritten to
`^1.1.0`, zero `workspace:` leaks.

Signed-off-by: Kavith Lokuhewage <kaviththiranga@gmail.com>
The Deploy and RuntimeHealthCard hooks resolve the observability API
via `useApi(observabilityApiRef)`, which throws NotImplementedError
when no factory is registered for the ref. When a host installs only
the Core plugin set (without @openchoreo/backstage-plugin-openchoreo-
observability), opening any component's Deploy tab crashes with:

  NotImplementedError: No implementation available for apiRef{
    plugin.openchoreo-observability.service
  }

Both hooks already document the intent that observability should be
optional: useLogsSummary's existing comment notes "without requiring
a package dependency" and useIncidentsSummary already absorbs per-
call failures as zero incidents. The bug is just the choice of
Backstage API — useApi() throws when the ref is unregistered, while
useApiHolder().get() returns undefined.

Switch both hooks to useApiHolder().get() and short-circuit the
fetch when the api is missing:

- useIncidentsSummary now returns an empty Map (PipelineCanvas
  already optional-chains incidentsSummaries.get(name)?.activeCount).
- useLogsSummary now sets observabilityDisabled: true, which routes
  to the existing empty-state branch in RuntimeHealthCard (the same
  branch the backend uses when the cluster has observability off).

No UI changes — only the throw is gone.

Signed-off-by: Kavith Lokuhewage <kaviththiranga@gmail.com>
@kaviththiranga kaviththiranga changed the title fix(release): publish with yarn npm publish to rewrite workspace deps fix(release): publish-pipeline + Deploy-tab observability dependency May 20, 2026
Copy link
Copy Markdown

@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.

🧹 Nitpick comments (1)
package.json (1)

30-30: 💤 Low value

Inconsistency with workflow dist-tag handling.

The workflow dynamically sets the tag to latest or next based on prerelease detection, but this script hardcodes --tag latest. If someone manually runs yarn release:publish for a prerelease version, it would incorrectly publish to the latest dist-tag.

Consider documenting this limitation (script is for stable releases only) or parameterizing the tag. Since CI is the primary release path, this is a minor concern.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@package.json` at line 30, The "release:publish" npm script hardcodes --tag
latest which conflicts with the workflow that may set "next" for prereleases;
update the script (the "release:publish" entry) to accept a configurable
dist-tag (e.g., read from an environment variable like DIST_TAG or
npm_config_tag and default to "latest") or document in README that this script
is intended for stable releases only so manual runs won't accidentally publish
prereleases to "latest".
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@package.json`:
- Line 30: The "release:publish" npm script hardcodes --tag latest which
conflicts with the workflow that may set "next" for prereleases; update the
script (the "release:publish" entry) to accept a configurable dist-tag (e.g.,
read from an environment variable like DIST_TAG or npm_config_tag and default to
"latest") or document in README that this script is intended for stable releases
only so manual runs won't accidentally publish prereleases to "latest".

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5ad53294-68e0-4ec3-9e4d-e6261ae91748

📥 Commits

Reviewing files that changed from the base of the PR and between 7c89539 and c7672f1.

📒 Files selected for processing (5)
  • .github/workflows/release.yml
  • README.md
  • package.json
  • plugins/openchoreo/src/components/Environments/hooks/useIncidentsSummary.ts
  • plugins/openchoreo/src/components/RuntimeLogs/OverviewCard/useLogsSummary.ts
✅ Files skipped from review due to trivial changes (1)
  • README.md

@kaviththiranga kaviththiranga merged commit b0a4ff2 into openchoreo:main May 20, 2026
7 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants