Project Workflow and Releases
This guide covers how code changes is managed in the CustardUI project, and the steps required to publish new versions to NPM and GitHub.
We use a Simplified Gitflow model. It differs from the traditional Gitflow by not having a separate release branch, and preferring squashes for feature branches, but retaining merge commits for production releases. Using this Gitflow model ensures a stable production environment while allowing rapid iteration on features.
gitGraph %% Initial state commit id: "v2.1.0" tag: "v2.1.0" branch develop %% Feature Work on Beta Channel checkout develop branch feature/new-logic commit id: "Feature Work" checkout develop merge feature/new-logic id: "Squash to Dev" %% Production Release Process checkout main merge develop id: "Merge PR #Release-v2.2.0" tag: "v2.2.0" %% CRITICAL: The Sync Back checkout develop merge main id: "Sync v2.2.0 to Beta" %% Next cycle continues from the synced state commit id: "Next Feature"
| Branch | Purpose | Rule |
|---|---|---|
main | Stable Production. Reflects the current @latest NPM release. | No direct commits. Only merge via Merge Commit PR from develop. Production tags should live in the main branch. |
develop | Integration & Beta. Where features are combined and tested. | Primary branch for development. Base for all @beta releases. Beta tags should live in the develop branch. |
feature/* | New Features. Isolated work on specific tasks. | Branch off develop, merge via Squash PR into develop. |
develop: git checkout develop && git pull && git checkout -b feature/my-feature.develop. Once approved, merge it (prefer using squash and merge here).Dev docs are hosted at https://custardui.js.org/devdocs, and is updated with every commit or PR merge to the develop branch.
develop branch)Use these when features are on develop and need to be tested in a non-local environment.
# 0. Be on the develop branch
git checkout develop
# 1. Bump version (e.g., 2.1.0 -> 2.1.1-beta.0)
npm run bump:beta
# 2. Release to NPM (@beta tag)
npm login
npm run release:beta
# CICD handles deployment of Beta Docs
Beta docs are hosted at https://custardui.js.org/betadocs, and is updated on every beta release.
main branch)When develop is stable and ready for the public.
Create a PR from develop to main, with name e.g. Release v2.2.0. Merge via "Create a Merge Commit" on the GitHub UI.
AVOID using "Squash and Merge" Since
developis a long-lived branch, squashing creates a "history mismatch.", withmainanddevelophaving different commit hashes for same code. This causes massive, redundant merge conflicts for the next sync or production hotfix. Using a Merge Commit (commit has 2 parents) preserves the shared history and allows forgit bisectdebugging.
Publish Stable Release on NPM:
main locally, pull the merge, running the following commands:# 0. Be on the main branch
git checkout main
git pull origin main
# 1. Bump to stable (e.g., 2.1.1-beta.x -> 2.1.1)
npm run bump:X # Use :patch, :minor or :major
# 2. Publish and Tag
npm login
npm run release:prod
# CICD handles deployment of Production Docs
main back to develop, with name e.g. Sync: Release v2.2.0 back to develop, merging with a merge commit.
Why? This ensures the official versioning and the release "node" are integrated into the Beta channel. Because you used a Merge Commit in Step 1, this PR should be conflict-free.
gitGraph commit id: "v2.1.0" tag: "v2.1.0" branch develop checkout develop commit id: "Feature 1" commit id: "Feature 2" commit id: "Prepare Release" %% The PR from develop to main checkout main merge develop id: "Merge PR #Release-v2.2.0" tag: "v2.2.0" %% The 'Finalize' step (Back-merge) checkout develop merge main id: "Sync v2.2.0 back to Beta" %% Next Beta cycle starts here commit id: "Next Feature Start"
Production docs are hosted at https://custardui.js.org, and is updated on every production release.
main branch)If a critical bug is found on main that cannot wait for the next develop cycle, follow the hotfix flow to ensure production is patched and development remains in sync.
hotfix/* branch off main.main. Merge via "Create a Merge Commit." Crucial: Do not use "Squash and Merge." Squashing creates a new, unique commit hash on
mainthat does not exist on your other branches. This "breaks" the historical link between them and causes massive, redundant merge conflicts when you try to sync the fix back todevelop.
npm run bump:patch and npm run release:prod to publish the release.main back into develop immediately.
main instead of merging hotfix branch into develop? Ensures develop receives both the code fix AND the automated version bump/tag created by the pipeline. Because we used a Merge Commit in Step 3, Git recognizes the shared history, making sync a clean "fast-forward" merge.develop has diverged: You may encounter merge conflicts. This is a critical safety check to ensure the production fix is correctly integrated into your new "Beta" logic.develop changes, but still complete the merge. This syncs the version history and prevents "ghost" conflicts in future releases.gitGraph commit id: "v2.1.0" tag: "v2.1.0" branch develop checkout develop commit id: "Feature Work" %% Hotfix checkout main branch hotfix/fix-bug checkout hotfix/fix-bug commit id: "Critical Fix" %% Merge to Main (Deploy) checkout main merge hotfix/fix-bug id: "Merge to Main" tag: "v2.1.1" %% Sync to Develop (The proper way) checkout develop merge main id: "Sync Main to Dev"
To use CustardUI via CDN, update your script tags to the appropriate version tag.
@latest annotation)unpkg:
<script src="https://unpkg.com/@custardui/custardui@latest"></script>
<script src="https://unpkg.com/@custardui/custardui@beta"></script>
jsDelivr:
<script src="https://cdn.jsdelivr.net/npm/@custardui/custardui@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/@custardui/custardui@beta"></script>