juspay / juspay/blend-rescript
proposal: downstream binding preview flow for unreleased blend-design-system changes
- Dominant language
- ReScript
- Stars
- 1
- Forks
- 0
- Avg merge
- 2h 48m
- Merged PRs (30d)
- 4
Description
## 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@
```
**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@`
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-`.
2. `npm install --no-save @juspay/blend-design-system@` β 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@`.
Dev then installs **both** URLs together:
```bash
npm install \
https://pkg.pr.new/@juspay/blend-design-system@ \
https://pkg.pr.new/juspay/blend-rescript@
```
- π 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 #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-` 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 #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).
Contributor guide
Assessment
This issue has not been assessed yet.