Skip to content

proposal: downstream binding preview flow for unreleased blend-design-system changes #46

@jagguji

Description

@jagguji

Context

juspay/blend-design-system publishes a pkg.pr.new preview for every PR / push to dev (via their ci.yml preview job). A ReScript consumer can grab that preview by installing:

npm install https://pkg.pr.new/@juspay/blend-design-system@<sha>

Today's escape hatch: if the consumer writes their own bindings inline, they can use any new component / prop from that preview immediately. The bindings in @subham_/rescript-blend (this repo) are nice-to-have but not load-bearing.

The future we're moving toward: this package becomes the canonical source of ReScript bindings, and consumers stop writing local wrappers. The moment that happens, consuming an unreleased blend change requires a matching, unreleased binding — and we don't have a flow for that yet.

Problem

When a dev wants to test an unmerged blend PR from their ReScript app, they need two artefacts at matching versions:

  1. The preview @juspay/blend-design-system@<blend-sha>
  2. A preview of @juspay/rescript-blend where src/*.res has been regenerated against that blend SHA.

Without (2), any new component / prop in the blend preview is unreachable from ReScript — the app compiles against stale bindings that don't know the new API exists.

The existing sync-bindings.yml in this repo can generate the new bindings on workflow_dispatch, but it opens a PR and waits for human review and NPM release. That's fine for stable adoption (minutes → hours → days) but useless for "I want to try this blend PR right now."

Options

A. Manual generate + file: / yalc install

Dev clones blend-rescript, sets @juspay/blend-design-system to the pkg.pr.new URL in devDeps, runs npm run generate -- --all, then installs the resulting tree into their app via yalc or npm install file:../blend-rescript.

  • 👍 Works today, no infra changes
  • 👎 Every consumer repeats the toolchain setup (needs LITELLM_API_KEY etc.)
  • 👎 Nothing in CI guarantees the generated bindings actually compile

B. workflow_dispatch → open PR → merge → wait for NPM release

The current sync-bindings.yml path. Review-gated, safe, but slow — not a fit for "I just want to try this PR."

C. Upstream dispatch → regenerate in CI → publish matching pkg.pr.new preview ⭐️

Add a step to blend-design-system's ci.yml that, after publishing its own preview, fires a repository_dispatch (blend-preview-published) into this repo with payload { blend_sha, blend_spec }.

This repo reacts:

  1. Creates a branch preview/blend-<sha>.
  2. npm install --no-save @juspay/blend-design-system@<blend_spec> — pins to that exact preview.
  3. npm run generate -- --all — regenerate bindings.
  4. rescript format -c + npm run build — gate on green.
  5. Push the branch (does not open a PR — this is a preview, not a merge candidate).
  6. pkg.pr.new GitHub App picks up the branch push and publishes https://pkg.pr.new/juspay/blend-rescript@<blend-rescript-sha>.

Dev then installs both URLs together:

npm install \
  https://pkg.pr.new/@juspay/blend-design-system@<blend-sha> \
  https://pkg.pr.new/juspay/blend-rescript@<blend-rescript-sha>
  • 👍 Zero-friction for consumers — URLs appear automatically
  • 👍 CI proves the bindings at least compile against that blend preview
  • 👍 Previews expire with the branches, no garbage collection needed
  • 👎 Requires re-installing the pkg.pr.new GitHub App on this repo (was dropped in ci: remove pkg.pr.new per-PR preview publishing #44)
  • 👎 Requires a PAT on the blend side (BLEND_RESCRIPT_PAT, Actions: Write, Contents: Read on juspay/blend-rescript)
  • 👎 Uses the LiteLLM quota for every blend PR — meaningful cost if blend ships many PRs

D. Don't solve it

Tell consumers: if you need an unreleased blend API, write a one-file inline binding locally. Accepts that the "canonical bindings" story has a permanent escape hatch for unreleased blend.

  • 👍 Zero work
  • 👎 Defeats the purpose of making this repo canonical

Recommendation

C, but with two guardrails:

  • Preview-publish job runs only if the blend PR has a specific label (e.g. needs-rescript-preview). Default blend PRs skip it, which keeps LiteLLM cost bounded to the few PRs that actually need cross-language validation.
  • Generated preview branches named preview/blend-<sha> are auto-deleted by a nightly workflow if older than 14 days, so the repo doesn't accumulate hundreds of dead branches.

What to decide before implementation

  1. Re-install the pkg.pr.new GitHub App on this repo? (Was dropped in ci: remove pkg.pr.new per-PR preview publishing #44.)
  2. Opt-in via label vs. every blend PR? (Cost vs. coverage.)
  3. Who owns the BLEND_RESCRIPT_PAT secret on the blend side?
  4. Is auto-publishing previews off .res regenerated by an LLM acceptable without human review? (Arguments both ways — compile success is a strong signal, but runtime correctness isn't checked.)

Out of scope here

  • The in-repo bindings quality loop (already handled by sync-bindings.yml + 3-retry feedback).
  • Stable release adoption (already handled by the manual sync-bindings.yml + PR review path).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions