feat: add package-first release flow

This commit is contained in:
2026-03-20 15:10:46 +08:00
parent 3600f3fcd9
commit e13a60369d
16 changed files with 764 additions and 191 deletions
+17 -7
View File
@@ -1,8 +1,10 @@
# Registry Install and Upgrade
Cadence UI now supports a minimal internal registry flow for source-owned consumers.
The goal is not package publishing yet. The goal is to make one reviewed repo state
directly consumable by another app.
Cadence UI supports a source-copy registry flow for teams that want local ownership of
component source inside their own application.
This is the optional customization path. The default downstream consumption model is now
package install via `@ai-ui/ui`, with `@ai-ui/tokens` available for lower-level token imports.
## What the registry contains
@@ -52,12 +54,22 @@ required dependencies, and verifies that the copied source both typechecks and b
## Consumer install flow
Choose this flow when:
- your team wants to edit copied component code locally
- you expect app-specific divergence that would be awkward to upstream immediately
- you prefer source ownership over centralized package upgrades
If you just want to use Cadence UI in another app with the lowest maintenance overhead,
use the package flow in [docs/releasing.md](/Users/xd/project/cadence-ui/docs/releasing.md)
instead.
### 1. Pin the Cadence UI source
Consumers should install from a reviewed Cadence UI repo state, usually:
- the merge commit of a version PR, or
- a maintainer-created tag that points at that versioned commit
- the `cadence-ui-vX.Y.Z` tag created for the release, or
- the matching merge commit if the source-copy install must be tested before the tag is created
The consumer does not need this repo as a runtime dependency. It only needs access to
the checked-out source when running the installer.
@@ -130,7 +142,5 @@ This registry flow is intentionally minimal:
It does not yet:
- publish to npm
- host a remote registry API
- auto-tag or auto-publish releases
- resolve consumer-specific codemods during upgrade
+104 -143
View File
@@ -1,47 +1,63 @@
# Releasing
This repo is not fully on a public-package release pipeline yet, but it is ready to use
Changesets as the canonical record of release intent.
Cadence UI now uses a package-first release model.
The current goal is modest:
- version `@ai-ui/ui` and `@ai-ui/tokens` deliberately
- keep release notes attached to the changes that caused them
- avoid inventing ad hoc version bumps when the component system evolves
- make release intent enforceable in CI before package work merges
- keep the generated registry metadata aligned with versioned source
## Current assumptions
- The repository root is private.
- Workspace packages currently use explicit package versions even when they are not yet published.
- `@ai-ui/docs` is a consumer app, not a releasable package, so it is ignored by Changesets.
- Publishing mechanics and registry credentials are still to be added.
Because of that, this baseline is intentionally conservative.
## Packages in scope
Changesets should currently be used for:
Default downstream consumers should install:
- `@ai-ui/ui`
- `@ai-ui/tokens`
Package consumers should now prefer:
Add `@ai-ui/tokens` only when the consumer app imports token helpers or lower-level token CSS
directly.
- `@ai-ui/ui` for component imports
- `@ai-ui/ui/styles.css` for the combined token + skin stylesheet
The source-copy registry flow still exists, but it is the optional customization path, not the
default release target. See [docs/registry.md](/Users/xd/project/cadence-ui/docs/registry.md)
for that mode.
The lower-level entries remain available when needed:
## Release artifacts
- `@ai-ui/tokens/styles.css`
- `@ai-ui/ui/skins.css`
Each release now has three artifacts:
Changes to the docs app alone usually do not need a changeset.
- published packages for `@ai-ui/ui` and `@ai-ui/tokens`
- a repository tag in the form `cadence-ui-vX.Y.Z`
- a committed `registry/index.json` snapshot for source-copy consumers pinned to that tag
## Package policy
- `@ai-ui/ui` and `@ai-ui/tokens` are released as a fixed version pair
- `@ai-ui/ui` is the primary component import surface
- `@ai-ui/ui/styles.css` is the default stylesheet entrypoint for package consumers
- `@ai-ui/tokens` remains available for lower-level token helpers and direct CSS imports
- `apps/docs` is a consumer app, not a releasable package
The current workflows assume private scoped packages on the npm registry with `access:
restricted`. If this repo moves to another registry later, update the publish workflow and
consumer setup accordingly.
## Consumer install
Package consumers should install the packages directly:
```bash
pnpm add @ai-ui/ui
```
Then import from `@ai-ui/ui` and point Tailwind at the packaged source:
```tsx
import { Button } from "@ai-ui/ui";
```
```css
@import "tailwindcss";
@import "@ai-ui/ui/styles.css";
@source "../node_modules/@ai-ui/ui/src";
```
This flow is validated by `pnpm test:package:consumer`.
## When to create a changeset
Create a changeset when a merged change affects any consumer-facing surface of a releasable package:
Create a changeset when a merged change affects any consumer-facing package surface:
- new components or slots
- changed props or variants
@@ -63,159 +79,104 @@ If CI would otherwise require a changeset for one of those exceptions, apply the
Use semver pragmatically:
- `patch`: bug fixes, QA-only behavior fixes, docs fixes bundled with a small behavior correction
- `patch`: bug fixes, QA-only behavior fixes, or small consumer-visible corrections
- `minor`: new components, new props, new variants, new tokens, additive API work
- `major`: breaking prop changes, renamed slots or states, removed variants, contract changes that require consumer updates
- `major`: breaking contract changes that require consumer updates
When in doubt, bias toward `minor` over underselling a visible new surface.
Because `@ai-ui/ui` and `@ai-ui/tokens` are fixed together, version bumps move as a pair.
## Recommended workflow
## Local maintainer commands
### 1. Make the code change
Complete the implementation, docs, and tests first.
At minimum, run:
Run the release validation suite locally with:
```bash
pnpm lint
pnpm registry:check
pnpm typecheck
pnpm test
pnpm release:validate
```
Use the docs and smoke checks when the change touches behavior-heavy UI:
That command currently runs:
```bash
pnpm build:docs
pnpm test:registry:consumer
pnpm test:e2e:smoke
```
- lint
- typecheck
- package unit tests
- package builds
- registry metadata validation
- source-copy consumer smoke
- package consumer smoke
### 2. Create a changeset
After the change is ready, create a changeset entry for the affected package or packages.
Once `@changesets/cli` is installed in the repo, the intended command is:
Create a versioned release change with:
```bash
pnpm changeset
```
The generated markdown file should:
- select the impacted package(s)
- choose the correct version bump type
- include a short consumer-facing summary
### 3. Review internal dependency impact
This repo is configured to update internal dependencies with a patch bump.
That means if `@ai-ui/tokens` changes and `@ai-ui/ui` depends on it, the versioning step should
keep the dependency graph coherent without requiring manual package edits.
### 4. Version the packages
When it is time to cut a release manually, run the repo version step:
Apply pending version bumps locally with:
```bash
pnpm release:version
```
That step is expected to:
Publish the packages manually, if needed, with:
- update package versions
- update internal dependency ranges where needed
- consume the pending changeset files
- rebuild `registry/index.json` so the copy-in install metadata stays version-aligned
```bash
pnpm release:publish
```
Review the resulting package diffs carefully before merging.
## Automated release flow
On `main`, the repository also runs a `Release Version PR` workflow that opens or updates a
version PR with the same command. That workflow is intentionally limited to version-file updates;
it does not publish packages.
The automated release sequence is now:
### 5. Distribute the versioned source
1. A product or package PR merges to `main` with a changeset.
2. `Release Version PR` runs on `main`, executes `pnpm release:validate`, and opens or updates a version PR via Changesets.
3. A maintainer reviews and merges that version PR.
4. `Create Release Tag` detects the package version change on `main` and creates `cadence-ui-vX.Y.Z`.
5. `Publish Packages` runs on the tag push, validates the tagged commit again, and publishes `@ai-ui/ui` and `@ai-ui/tokens`.
Publishing is not fully wired in this repo yet, so the consumable artifact is the versioned
repository state itself.
After the version PR merges:
- keep the merge commit as a stable install point, or create a maintainer tag for it
- treat the committed `registry/index.json` as the install contract for that repo state
- point consumers at that commit or tag when they run `pnpm registry:install`
See [docs/registry.md](/Users/xd/project/cadence-ui/docs/registry.md) for the consumer
install and upgrade flow.
The tag is the stable source reference for source-copy consumers. The packages are the default
artifact for package consumers.
## CI workflows
### Pull request check
The `Changeset Status` workflow runs on pull requests and enforces a simple rule:
`Changeset Status` runs on pull requests and:
- if a PR changes `@ai-ui/ui` or `@ai-ui/tokens`, it should usually include a new
`.changeset/*.md` file
- if the work is intentionally non-releasable, maintainers can apply the
`no-changeset-needed` label
When a changeset is present, the workflow also runs:
```bash
pnpm changeset:status --since origin/main
```
This validates that pending changesets resolve cleanly against the base branch.
The workflow also runs:
```bash
pnpm registry:check
```
This prevents registry metadata drift from merging unnoticed.
The repo also runs:
```bash
pnpm test:registry:consumer
```
This verifies that the committed registry snapshot can still install into a fresh
consumer app, typecheck, and build.
- requires a changeset for releasable package changes unless `no-changeset-needed` is applied
- validates pending changesets
- checks that `registry/index.json` is current
- runs the source-copy consumer smoke test
- runs the package consumer smoke test
### Version PR workflow
The `Release Version PR` workflow runs on pushes to `main` and on manual dispatch. It:
`Release Version PR` runs on pushes to `main` and:
- installs dependencies
- runs `pnpm release:version`
- opens or updates a version PR using `changesets/action`
- runs `pnpm release:validate`
- opens or updates the version PR with `pnpm release:version`
This is still a versioning skeleton, not a publish pipeline, but the version PR now refreshes
the committed registry metadata that consumers install from.
### Tag workflow
## Future publish prerequisites
`Create Release Tag` runs on pushes to `main` and:
Before turning the version workflow into a publish workflow, the repo still needs:
- detects when the fixed package version pair changed
- creates `cadence-ui-vX.Y.Z`
- a root publish script, for example `pnpm changeset publish` or a guarded wrapper around it
- registry credentials such as `NPM_TOKEN`
- a decision on which workspace packages should actually be published versus versioned internally
- any extra validation that must run before publish is allowed
### Publish workflow
`Publish Packages` runs on `cadence-ui-v*` tags and:
- verifies the tag matches the package version
- runs `pnpm release:validate`
- publishes the packages with `NPM_TOKEN`
## Required secrets
The publish workflow currently requires:
- `NPM_TOKEN`: token with publish access to the `@ai-ui` scope on the configured npm registry
## Notes for maintainers
- Keep `packages/ui/src/index.ts` and package exports aligned with any release-worthy surface.
- Keep `packages/ui/src/index.ts` and package exports aligned with the published surface.
- Keep `registry/index.json` in sync even though package publish is now the default; source-copy consumers still rely on it.
- If a component lands without docs or tests, it should not move toward release yet.
- Prefer one clear changeset per consumer-visible change rather than bundling unrelated work.
- If a PR contains both infra and component work, separate the release notes so consumers can
understand what actually changed.
## Main-thread follow-up still needed
This baseline now covers changeset intent checks in PRs, registry metadata validation, and
version PR creation on `main`. What remains is the publish decision, tagging policy, and any
registry-specific automation beyond source-copy installs.