Skip to content

Fix empty constants in published package - #378

Merged
marcospassos merged 1 commit into
masterfrom
fix-empty-release-constants
Aug 26, 2026
Merged

Fix empty constants in published package#378
marcospassos merged 1 commit into
masterfrom
fix-empty-release-constants

Conversation

@marcospassos

Copy link
Copy Markdown
Member

Problem

@croct/plug@0.24.0 is published with every constant empty (unpkg):

const CDN_URL = "";
const PLAYGROUND_ORIGIN = "";
const PLAYGROUND_CONNECT_URL = "";
const PREVIEW_WIDGET_ORIGIN = "";
const PREVIEW_WIDGET_URL = "";

Reported by a user on @croct/plug-next@0.11.0. Since PREVIEW_WIDGET_URL is empty, the iframe src built in src/plugins/preview/index.ts:102 becomes a relative URL, so the page frames itself instead of the CDN and gets blocked by the host's own frame-ancestors. The widget never renders. The empty PREVIEW_WIDGET_ORIGIN independently breaks the postMessage origin check in src/plugins/preview/index.ts:128, so fixing only the URL would not be enough.

The empty CDN_URL also silently disables app ID auto-detection: detectAppId() in src/plug.ts:106 queries script[src^=''], which never matches.

Cause

#373 moved the publish to a reusable workflow and passed the substitution commands as the prepare-script input. A caller's workflow-level env block is not propagated to a called reusable workflow, and publish-public-npm-package.yml defines no env of its own, so ${CDN_URL} and the rest were unset in that runner. Actions runs bash -eo pipefail without -u, so the unset variables expanded to empty strings and sed happily replaced each <@placeholder@> with nothing. The publish succeeded.

That also explains why only the npm package is affected:

  • $GITHUB_REF_NAME is a runner default variable, so the version was set correctly.
  • The cdn and preview-widget jobs are ordinary jobs in this workflow, so their variables did resolve — widget-0.24.0.html is on the CDN and returns 200.

Note that ${{ env.X }} is not a workaround either: the env context is unavailable in jobs.<job_id>.with.<input>.

Fix

Move the prepare step into prepare-release.mjs, so the values live in the repository instead of in workflow environment variables, and fail the release if any placeholder or empty constant survives — the check that would have caught this before publishing. release-config.mjs holds the values, and the bundle and widget jobs derive their variables from it, so there is a single source of truth rather than a second copy that can drift.

Also in this PR:

  • deploy-preview.yaml substituted <@version@>, <@baseEndpointUrl@> and <@maxQueryLength@>, none of which exist in this package — they were copy-pasted from the SDK. PR previews have therefore always shipped literal <@cdnUrl@> placeholders, since well before #373. The preview now pins constants to the latest release tag, so PREVIEW_WIDGET_URL points at a widget that exists.
  • The preview-widget job cached path: node_modules keyed on the root lockfile while running npm ci in preview/, using the same cache key as the cdn job. A cache hit from cdn would make it skip installing the widget dependencies and fail the build. Now matches the pattern already used in validate-preview.yaml.

Verification

Each path was run locally:

  • Release — output is byte-identical to what 0.23.0 published, with the version swapped.
  • PR preview — resolves to widget-0.23.0.html (latest tag at the time of testing).
  • CDN bundle — rollup still inlines the correct values into plug.min.js.
  • Guards — a stray placeholder and a missing version both exit 1.

Out of scope

@croct/sdk@0.22.0 ships MAX_QUERY_LENGTH = parseInt("<@maxQueryLength@>", 10)NaN (BASE_ENDPOINT_URL and VERSION are substituted, only that one is missed). Same bug class in sdk-js, and it leaks into the CDN plug.min.js, which bundles the SDK. The placeholder check here is deliberately scoped to the build output and not the bundle, so releases are not blocked on a dependency's defect.

Follow-up

npm does not allow republishing 0.24.0, so this needs a 0.24.1 tag to reach users.

The release workflow passes the substitution commands as the
`prepare-script` input of a reusable workflow. Workflow-level `env` is not
propagated to called workflows, so `${CDN_URL}` and friends were unset in
that runner and `sed` replaced every `<@Placeholder@>` with an empty string.

That shipped 0.24.0 with empty constants: `PREVIEW_WIDGET_URL` became a
relative URL, so the preview widget iframe framed the host page instead of
the CDN, and the empty `PREVIEW_WIDGET_ORIGIN` broke the postMessage origin
check. The empty `CDN_URL` also disabled the app ID auto-detection, since
`script[src^='']` never matches.

Move the whole prepare step into `prepare-release.mjs`, so the values live
in the repository rather than in workflow environment variables, and fail
the release when a placeholder or an empty constant survives. The bundle and
widget jobs read the same values from `release-config.mjs` to keep a single
source of truth.

Also replace the substitutions in the preview workflow, which targeted
placeholders that do not exist in this package, and fix the preview widget
job caching the root `node_modules` under the same key as the bundle job,
which could skip installing the widget dependencies.
@marcospassos marcospassos added the bug Something isn't working label Aug 26, 2026
@pkg-pr-new

pkg-pr-new Bot commented Aug 26, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@croct/plug@378

commit: beb32a9

@marcospassos
marcospassos merged commit caeab3f into master Aug 26, 2026
12 checks passed
@marcospassos
marcospassos deleted the fix-empty-release-constants branch August 26, 2026 18:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant