Repository navigation
Release Process
Tiếng Việt: Release-Process-vi.
This page covers the stable channel (main → latest). Prereleases on next, canary and fixes for older minors on release/X.Y: Branching and Release Channels.
Versions follow SemVer. Before 1.0, a minor release may contain breaking changes; always call them out.
These rules apply to releases after 0.12.0 (RULES_SINCE in scripts/release-rules.mjs), for yugen-ui and
@yugen-ui/cli. The goal: most changes ship in patch releases, and the minor and major numbers don't go up for small changes.
| Number | Bump when | Don't bump for | Cadence |
|---|---|---|---|
PATCH x.y.Z
|
Bug fixes (including bugs from the previous release), a11y, performance, wrong TS types, small UI tweaks | New API, breaking changes | No limit; group fixes that land close together |
MINOR x.Y.0
|
At least one new API (component, prop, prop value, token, export, template); deprecations; before 1.0 also breaking changes | Only fixes / tweaks | One per milestone, ≥ 14 days after the previous minor |
MAJOR X.0.0
|
Breaking changes, from 1.0; removes all deprecated APIs at once, with a migration guide | Non-breaking features | ≥ 180 days after the previous major |
- No skipped numbers: after
0.12.0comes0.12.1or0.13.0. - Changes only to the docs site, tests or CI are not released; the Docs workflow deploys them on its own.
-
mainandrelease/X.Yonly ship patch releases (hotfixes). Features go intonextand are released when the milestone closes. - Prereleases (
-next.N,cli@X.Y.Z-beta.N, canary) don't count. -
create-yugen-uihas no cadence of its own: it moves up a minor together with@yugen-ui/cli(CLI rule 2).
Automatic checks:
-
npm run check:changesets(CI) flags:majorbefore 1.0;majorwithout "Breaking:"; "Breaking:" in apatch; a summary starting with "Fix" in aminor, or "New" in apatch; aminor/majorin PRs intomain/release/*(exceptnext → main). -
check:release(repo root and CLI) reads the type (## Mới,## Sửa lỗi…) of the news entries insrc/docs/news(the current version and theupcomingentry on next): a patch release has nonew/breaking; a minor release has at least onenew(before 1.0: orbreaking); from 1.0,breakingonly in a major release; a major has at least onebreaking; no skipped numbers; the minor / major cadence is measured from the newsdate.
Want to release a minor sooner than 14 days? There is no way around it in the script. Features wait for the milestone; fixes ship in a patch release.
npx changeset → choose patch (bug fix) / minor (feature, deprecation) / major (from 1.0, API removal) → write one sentence for
users (in English, as in the CHANGELOG). The file goes in .changeset/*.md.
PRs into next with user-visible changes also add a line to the upcoming news (section below).
Each release is two Markdown files, Vietnamese and English, in src/docs/news/<package>/ (yugen-ui, cli,
create-yugen-ui): 0.14.0.vi.md and 0.14.0.en.md. The version number comes from the file name.
---
date: 2026-11-11
upcoming: true
---
# AppShell, Sortable và trang Người đóng góp
Một đoạn tóm tắt.
## Mới
- AppShell và Sidebar: … `layout="header"` cho thanh trên cùng trải ngang. [→](/components/appshell)
## Sửa lỗi
- …- The change type is a
##heading:Mới,Cải tiến,Sửa lỗi,Thay đổi lớn(en version:New,Improved,Fixed,Breaking). One- …line per item; the[→](/path)at the end is the "View" button to the docs page. - Items may use inline Markdown:
`code`for props, functions, files, commands; component names in lowercase. - The vi and en versions must match: same
date,upcoming, number of items, types and links, in the same order.node scripts/check-news.mjschecks this (a few seconds, nonpm cineeded); the docs build reports the same errors with file and line. - PRs that only change
src/docs/news/**don't run the full CI, only theNewsworkflow. After merge, Pages rebuilds the docs.
News for the next release is written step by step on next, not left until release time.
- The newest file in the package folder has
upcoming: truein its frontmatter, in both the vi and en versions. The file name is the number the next release will have (npx changeset status; for the CLI, by the CLI's SemVer rules), anddateis the planned date (the milestone's due date). - Each PR into
nextwith user-visible changes adds an item to both files, creating them if they don't exist yet. Changesets are still required as before; the news is the part for docs readers. - The What's new page shows this entry with the Upcoming label and the date "Planned for …". Preview it at
/next/(https://trandat1114.github.io/Yugen-UI/next/): the docs rebuild fromnextafter every push. - Only the newest version may be
upcoming.check-releaseaccepts it when its version is greater thanpackage.json, and fails whenpackage.jsonalready equals that version while the news is stillupcoming(it was not finalized), or when a tag exists. -
upcomingnews reachesmainthrough thenext → mainPR and is finalized in thechore(release)commit: removeupcoming, fill in the release date in both files, review the content against the CHANGELOG.
git pull
npm run version-packages # changeset version → bump package.json, write the CHANGELOG, sync templates, lockfile- News in
src/docs/news/yugen-ui: if there is already anupcomingentry (written on next), removeupcoming, fill in the release date in both.vi.mdand.en.mdand review the content; if there is none, add two files for the new version (see News on the What's new page). - Add the link
[x.y.z]: …/releases/tag/vx.y.zat the end of the CHANGELOG. Updatesrc/docs/roadmap.ts: set the items of the finished milestone todone, move the milestone to Released (remove it fromnow, movenextup), then runnpm run roadmap(writes ROADMAP.md;roadmap.test.tsfails if they differ). npm run check:release && npm test && npm run build- Commit
chore(release): vx.y.z, push, wait for CI to be green. - Tag and push the tag:
git tag vx.y.z
git push origin vx.y.zThe Release workflow checks that the tag matches package.json and is on the right branch, runs the tests, builds and packs
the package. The publish job then waits for your approval (environment npm-release, see
Release jobs and approval): open the run › Review deployments › approve. It runs
npm publish --provenance on the packed .tgz through npm trusted publishing (no token). The dist-tag is chosen by
scripts/release-channel.mjs: latest, next (prerelease) or release-X.Y.
After publishing, the workflow creates a GitHub Release for the tag from that version's CHANGELOG entry (scripts/release-notes.mjs;
the latest release is marked Latest, prereleases are marked Pre-release). The Docs workflow rebuilds the site (including docs for
older minors under /vX.Y/). The maintainer posts a summary in Discussions Announcements.
The README is the front page on GitHub and npm, so it must be reviewed before a major release. Add the following to the
chore(release) commit, after step 2 above:
- Installation and requirements: the install command, peer dependencies (React, Tailwind CSS) and minimum Node.js match the new release.
- Examples: the code in the README runs with the new API, with no removed or deprecated APIs left.
- Features: the feature list, component count, themes and brands match the docs.
- Links: docs, the migration guide from the previous major, CHANGELOG, npm.
- Fix what needs fixing, then write
<!-- readme-reviewed: X.0.0 -->at the top ofREADME.md, even if nothing needed fixing.check:releaseblocks the release PR of a major if this marker is missing or still names the previous major. Minor, patch and prerelease (-rc.N) versions don't need it.
A CLI major works the same way with packages/cli/README.md (commands, options, Node.js requirement, examples); the CLI's
check-release checks the same marker.
Fix on main → patch changeset → repeat the process (e.g. 0.6.1). Never republish the same version number; npm doesn't allow it.
Hotfixes are patch releases only: check:changesets blocks minor / major changesets in PRs into main.
Two packages in packages/ (packages/cli → npm @yugen-ui/cli, the command after install is yugen;
packages/create-yugen-ui → npm create-yugen-ui), released separately from yugen-ui: tag cli@X.Y.Z, workflow
Release CLI (.github/workflows/release-cli.yml). They don't use Changesets: the version and CHANGELOG are edited by hand.
User docs: #/concepts/cli.
The unscoped name yugen can't be used: npm returns 403 "Package name too similar to existing package hygen". Scoped packages
are not subject to this check; the @yugen-ui scope is an npm org (free).
packages/cli/scripts/check-release.mjs checks rules 1–4 automatically (in CI and at release time).
-
CHANGELOG and What's new: each version has a
## X.Y.Zsection at the top ofpackages/cli/CHANGELOG.md(changes to both packages are recorded together here), and a news entry insrc/docs/news/cli(the@yugen-ui/clitab on/news). Whencreate-yugen-uichanges version, also add news insrc/docs/news/create-yugen-ui. Write both Vietnamese and English, with a link to/concepts/cli. CLI prereleases need no news entry. During development, PRs that changepackages/cliadd a line to the## Unreleasedsection of the CHANGELOG; at release time, renameUnreleasedto the version number. -
create-yugen-uifollows the CLI:packages/create-yugen-ui/package.jsondeclares"@yugen-ui/cli": "^X.Y.0". Before 1.0,^0.1.0does not accept0.2.0: when the CLI moves up a minor, update the dependency and bump thecreate-yugen-uiversion in the same commit. A CLI patch release doesn't require republishingcreate-yugen-ui. -
Templates follow
yugen-ui: templates live in the CLI package and pinyugen-ui@^<current version>. After every minor release ofyugen-ui, release the CLI (patch) so thatcreatemakes apps with the new version. The CLI can only be published after thatyugen-uiversion is on npm:check-release --tagblocks it otherwise. Before then, the CI jobTemplate · …builds the templates with annpm packof the same commit, so the release PR doesn't need the published version. -
Never reuse a version, including unpublished ones: npm blocks them permanently, and
npm viewdoesn't show unpublished versions. Check withnpm run check:release -- --npm. For a broken version usenpm deprecate, not unpublish. -
Branches: stable versions are tagged on
main(dist-taglatest); prereleasescli@X.Y.Z-beta.Nare tagged onnext(dist-tagnext, try them withnpx @yugen-ui/cli@next).create-yugen-uiis only released with stable versions. -
CLI SemVer:
patch: bug fixes, template updates;minor: new commands or options, changes to theyugen.jsonformat, new templates. Before 1.0, breaking changes (renamed commands / options, files written to a different place) are alsominor, called out in the CHANGELOG. Cadence and news follow the rules for each number (src/docs/news/cli). -
The registry is a contract:
yugen add/initreadpublic/r, generated byscripts/build-registry.mjs(item names, pathsregistry/yugen/{ui,lib}/…, imports@/lib/@/components/ui, the itemstheme,cn,yugen-provider,all). If you change any of these, release a compatible CLI before the docs (and registry) deploy. -
Publish only through tags to get provenance: no
npm publishfrom a personal machine.
git switch main && git pull
# 1. Bump "version" in packages/cli/package.json (+ packages/create-yugen-ui/package.json under rule 2)
# 2. Rename "## Unreleased" to "## X.Y.Z" at the top of packages/cli/CHANGELOG.md
# 3. Finalize the upcoming news in src/docs/news/cli (and news/create-yugen-ui if create-yugen-ui changes version):
# remove upcoming, fill in the release date in both .vi.md and .en.md; if there is none, add two files for the new version
# 4. Update the cli X.Y.Z milestone in src/docs/roadmap.ts, then npm run roadmap (from the repo root)
cd packages/cli
npm install --package-lock-only # version in the lockfile
npm run check:release -- --npm # rules 1–4 (--npm needs network access)
npm test
npm run smoke # npm pack both packages → install from the .tgz → create-yugen-ui with every templateCommit chore(release): cli X.Y.Z, merge into main, wait for CI to be green (CLI job), then:
git switch main && git pull
git tag cli@X.Y.Z
git push origin cli@X.Y.ZRelease CLI runs check-release.mjs --tag (the tag matches the version, the branch is right, the version was never unpublished, the yugen-ui version pinned by the templates is on npm → pick the dist-tag),
typecheck, test, smoke and packs both packages. After your approval (environment npm-release, as for Release) it runs
npm publish --provenance for @yugen-ui/cli, then create-yugen-ui. Each package is skipped if that version is already
on npm, so when a publish step fails (token, package name), fix the cause and just Re-run the failed jobs.
npx @yugen-ui/cli@latest --version
npx create-yugen-ui@latest smoke-app --template starter
cd smoke-app && npm run buildThe docs deploy from main puts the news entry on #/news (the @yugen-ui/cli / create-yugen-ui tab) and turns on the "new" dot
in the top bar for people who saw the previous version. Release CLI creates a GitHub Release for the tag from the section in
packages/cli/CHANGELOG.md (not marked Latest, so the repo page keeps showing the yugen-ui release). Broken after publishing: fix on
main and release a patch; deprecate the broken version with npm deprecate @yugen-ui/cli@X.Y.Z "…" (don't unpublish).
Since 0.14.0 and CLI 0.6.0 every publish goes through OIDC; the repository has no npm token. Both release workflows use
npm ≥ 11.5.1 and give permissions: id-token: write to their publish jobs only. On npmjs.com, each package › Settings ›
Trusted Publisher › GitHub Actions:
- repository
trandat1114/Yugen-UI, workflowrelease.ymlforyugen-ui(stable, prerelease and canary builds);release-cli.ymlfor@yugen-ui/cliandcreate-yugen-ui. No environment. -
Allow npm publish checked. Without it the publish step fails with
E403 … OIDC permission denied for this action. -
Allow npm dist-tag unchecked: dist-tags are set by
npm publish --tag.
npm accepts one trusted publisher workflow per package, which is why the canary jobs live in release.yml. A new package
needs a first manual npm publish before its trusted publisher can be set. The trusted publisher is bound to the workflow
file name: don't rename release.yml or release-cli.yml.
Any job that can request the npm OIDC token can publish a version with valid provenance. So the jobs that hold it run no code from the repository or its dependencies (#379):
| Job | Permissions | Runs |
|---|---|---|
build (canary-build) |
contents: read |
npm ci, release checks, tests, build, npm pack. Uploads the .tgz files and SHA256SUMS as an artifact. |
publish (canary-publish) |
id-token: write |
setup-node only, with a check that its npm is ≥ 11.5.1 (no npm install -g npm: an unpinned download). Downloads the artifact, checks SHA256SUMS against the hash reported by build, then npm publish <file>.tgz --provenance --ignore-scripts. No checkout, no npm ci, no repo scripts. |
github-release |
contents: write |
Checkout and scripts/release-notes.mjs → GitHub Release. Then scripts/release-provenance.mjs attaches the tarball and its SLSA provenance (<file>.tgz.intoto.jsonl, the Sigstore bundle npm recorded at publish), after checking both against the build tarball's sha512. No id-token. |
release-cli.yml has the same three jobs; its publish job publishes @yugen-ui/cli first, then create-yugen-ui.
The publish jobs of release.yml and release-cli.yml use the GitHub environment npm-release (repository
Settings › Environments): required reviewer trandat1114, deployments only from tags v* and cli@*. After you
push a tag, the run stops before publish until you open it and choose Review deployments › Approve and deploy.
Rejecting it stops the release; nothing is published and no GitHub Release is created. To try again later, re-run the
workflow. The canary jobs don't use the environment, so every push to canary publishes without approval.
The Environment field of the npm trusted publisher stays empty: yugen-ui has one trusted publisher for both canary and
stable builds, and naming npm-release there would block every canary.
- On npmjs.com: Add Organization → name
yugen-ui(public packages, free). - Publish the first version by hand (
npm publish --access publicwith 2FA), then declarerelease-cli.ymlas the trusted publisher (see above). - Tag
cli@0.1.0onmainas above.
Yugen UI © trandat1114 · MIT · Inspired by Microsoft Fluent 2, not a Microsoft product · Edit the wiki through the wiki/ folder · Lấy cảm hứng từ Microsoft Fluent 2, không phải sản phẩm của Microsoft · Sửa wiki qua thư mục wiki/
Use
Develop
Project
Tiếng Việt
- Trang chủ
- Bắt đầu
- Theme & token
- Câu hỏi thường gặp
- Kiến trúc
- Viết component
- Kiểm thử & CI
- Viết nội dung
- Nhánh & kênh phát hành
- Phát hành
- Cộng đồng & phân loại
- Sổ tay vận hành
Links