mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-15 02:16:27 +00:00
feat(release): implement semantic versioning automation with conventional commits
- Add semantic-release for automated npm publishing - Add commitlint + husky for commit message enforcement - Add professional branching strategy (beta → main workflow) - Create .releaserc.json with multi-branch config - Create sync-version-plugin.cjs for VERSION file sync - Update release.yml workflow (Node.js 22 required) - Update CLAUDE.md and CONTRIBUTING.md with new workflow - Deprecate manual bump-version.sh script
This commit is contained in:
1 parent
72c2b08715
commit
d3d96371de
13 files changed
+1737
-142
No files matched your search
+39
-15
@@ -1,12 +1,46 @@
|
||||
#!/usr/bin/env bash
|
||||
# Bump CCS version
|
||||
# Usage: ./scripts/bump-version.sh [major|minor|patch]
|
||||
# =============================================================================
|
||||
# DEPRECATED: This script is kept for emergency manual releases only.
|
||||
#
|
||||
# v4.5.0+: Bootstrap architecture - shell scripts delegate to Node.js
|
||||
# Version is maintained in: VERSION, package.json, installers/*
|
||||
# Releases are now automated via semantic-release:
|
||||
# - Merge to main → stable release (npm @latest)
|
||||
# - Merge to beta → beta release (npm @beta)
|
||||
#
|
||||
# Version is determined automatically from conventional commits:
|
||||
# - feat: commit → MINOR bump (5.0.2 → 5.1.0)
|
||||
# - fix: commit → PATCH bump (5.0.2 → 5.0.3)
|
||||
# - feat!: commit → MAJOR bump (5.0.2 → 6.0.0)
|
||||
#
|
||||
# See: docs/version-management.md
|
||||
# =============================================================================
|
||||
#
|
||||
# Legacy usage (emergency only): ./scripts/bump-version.sh [major|minor|patch]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Show deprecation warning
|
||||
echo "============================================================="
|
||||
echo "[!] DEPRECATED: This script is for emergency use only."
|
||||
echo ""
|
||||
echo " Releases are now automated via semantic-release."
|
||||
echo " Simply merge to 'main' or 'beta' branch."
|
||||
echo ""
|
||||
echo " Version is determined from conventional commits:"
|
||||
echo " feat: commit -> MINOR (5.0.2 -> 5.1.0)"
|
||||
echo " fix: commit -> PATCH (5.0.2 -> 5.0.3)"
|
||||
echo " feat!: commit -> MAJOR (5.0.2 -> 6.0.0)"
|
||||
echo "============================================================="
|
||||
echo ""
|
||||
|
||||
# Require explicit confirmation
|
||||
read -p "Continue with manual bump? (y/N) " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "Cancelled. Use conventional commits + merge to main instead."
|
||||
exit 0
|
||||
fi
|
||||
echo ""
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CCS_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
VERSION_FILE="$CCS_DIR/VERSION"
|
||||
@@ -69,17 +103,7 @@ echo "Note: lib/ccs and lib/ccs.ps1 are now bootstraps"
|
||||
echo " (delegate to Node.js, no version hardcoded)"
|
||||
echo ""
|
||||
|
||||
# Auto-confirm in non-interactive mode (CI, piped, etc.)
|
||||
if [[ ! -t 0 ]]; then
|
||||
echo "[i] Non-interactive mode detected, proceeding..."
|
||||
else
|
||||
read -p "Continue? (y/N) " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "Cancelled."
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
# Already confirmed above in deprecation warning
|
||||
|
||||
# Update VERSION file
|
||||
echo "$NEW_VERSION" > "$VERSION_FILE"
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* semantic-release plugin to sync VERSION file
|
||||
*
|
||||
* semantic-release updates package.json but not the VERSION file.
|
||||
* This plugin keeps VERSION in sync for shell scripts and installers.
|
||||
*/
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* Called during the prepare step before git commit
|
||||
*/
|
||||
prepare(_pluginConfig, context) {
|
||||
const { nextRelease, logger } = context;
|
||||
const versionFile = path.join(process.cwd(), 'VERSION');
|
||||
|
||||
// Write version without 'v' prefix (e.g., "5.1.0" not "v5.1.0")
|
||||
const version = nextRelease.version;
|
||||
fs.writeFileSync(versionFile, version + '\n');
|
||||
logger.log('[sync-version-plugin] Updated VERSION file to %s', version);
|
||||
|
||||
// Also update installers for standalone installs
|
||||
const installSh = path.join(process.cwd(), 'installers', 'install.sh');
|
||||
const installPs1 = path.join(process.cwd(), 'installers', 'install.ps1');
|
||||
|
||||
if (fs.existsSync(installSh)) {
|
||||
let content = fs.readFileSync(installSh, 'utf8');
|
||||
content = content.replace(/^CCS_VERSION=".*"/m, `CCS_VERSION="${version}"`);
|
||||
fs.writeFileSync(installSh, content);
|
||||
logger.log('[sync-version-plugin] Updated installers/install.sh');
|
||||
}
|
||||
|
||||
if (fs.existsSync(installPs1)) {
|
||||
let content = fs.readFileSync(installPs1, 'utf8');
|
||||
content = content.replace(/^\$CcsVersion = ".*"/m, `$CcsVersion = "${version}"`);
|
||||
fs.writeFileSync(installPs1, content);
|
||||
logger.log('[sync-version-plugin] Updated installers/install.ps1');
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in new issue
Block a user