fix: implement automated version management to prevent version mismatches
Fixes #27 ## Problem Version 2.5.5 was displaying as 2.5.0 in the updater because package.json wasn't updated when the git tag was created. ## Solution This PR implements a comprehensive automated version management system: ### 1. Version Bump Script (scripts/bump-version.js) - Automates version updates in package.json - Creates git commits and tags automatically - Prevents human error in version management - Supports semver bumps (major/minor/patch) or specific versions ### 2. Version Validation Workflow (.github/workflows/validate-version.yml) - Runs automatically on every git tag push - Validates package.json version matches the git tag - Fails CI if versions mismatch with clear error messages - Prevents releases with incorrect versions ### 3. Documentation (RELEASE.md) - Complete release process guide - Troubleshooting for version issues - Release checklist ### 4. Updated package.json - Fixed current version from 2.5.0 to 2.5.5 ## Impact - ✅ Prevents version mismatch issues from happening again - ✅ Automates release process - ✅ CI validation catches manual errors - ✅ Clear documentation for maintainers
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
name: Validate Version
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
jobs:
|
||||
validate-version:
|
||||
name: Validate package.json version matches tag
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Extract version from tag
|
||||
id: tag_version
|
||||
run: |
|
||||
# Extract version from tag (e.g., v2.5.5 -> 2.5.5)
|
||||
TAG_VERSION=${GITHUB_REF#refs/tags/v}
|
||||
echo "version=$TAG_VERSION" >> $GITHUB_OUTPUT
|
||||
echo "Tag version: $TAG_VERSION"
|
||||
|
||||
- name: Extract version from package.json
|
||||
id: package_version
|
||||
run: |
|
||||
# Read version from package.json
|
||||
PACKAGE_VERSION=$(node -p "require('./auto-claude-ui/package.json').version")
|
||||
echo "version=$PACKAGE_VERSION" >> $GITHUB_OUTPUT
|
||||
echo "Package.json version: $PACKAGE_VERSION"
|
||||
|
||||
- name: Compare versions
|
||||
run: |
|
||||
TAG_VERSION="${{ steps.tag_version.outputs.version }}"
|
||||
PACKAGE_VERSION="${{ steps.package_version.outputs.version }}"
|
||||
|
||||
echo "=========================================="
|
||||
echo "Version Validation"
|
||||
echo "=========================================="
|
||||
echo "Git tag version: v$TAG_VERSION"
|
||||
echo "package.json version: $PACKAGE_VERSION"
|
||||
echo "=========================================="
|
||||
|
||||
if [ "$TAG_VERSION" != "$PACKAGE_VERSION" ]; then
|
||||
echo ""
|
||||
echo "❌ ERROR: Version mismatch detected!"
|
||||
echo ""
|
||||
echo "The version in package.json ($PACKAGE_VERSION) does not match"
|
||||
echo "the git tag version ($TAG_VERSION)."
|
||||
echo ""
|
||||
echo "To fix this:"
|
||||
echo " 1. Delete this tag: git tag -d v$TAG_VERSION"
|
||||
echo " 2. Update package.json version to $TAG_VERSION"
|
||||
echo " 3. Commit the change"
|
||||
echo " 4. Recreate the tag: git tag -a v$TAG_VERSION -m 'Release v$TAG_VERSION'"
|
||||
echo ""
|
||||
echo "Or use the automated script:"
|
||||
echo " node scripts/bump-version.js $TAG_VERSION"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✅ SUCCESS: Versions match!"
|
||||
echo ""
|
||||
|
||||
- name: Version validation result
|
||||
if: success()
|
||||
run: |
|
||||
echo "::notice::Version validation passed - package.json version matches tag v${{ steps.tag_version.outputs.version }}"
|
||||
@@ -81,6 +81,21 @@ auto-claude/.venv/bin/pytest tests/ -m "not slow"
|
||||
python auto-claude/validate_spec.py --spec-dir auto-claude/specs/001-feature --checkpoint all
|
||||
```
|
||||
|
||||
### Releases
|
||||
```bash
|
||||
# Automated version bump and release (recommended)
|
||||
node scripts/bump-version.js patch # 2.5.5 -> 2.5.6
|
||||
node scripts/bump-version.js minor # 2.5.5 -> 2.6.0
|
||||
node scripts/bump-version.js major # 2.5.5 -> 3.0.0
|
||||
node scripts/bump-version.js 2.6.0 # Set specific version
|
||||
|
||||
# Then push to trigger GitHub release workflows
|
||||
git push origin main
|
||||
git push origin v2.6.0
|
||||
```
|
||||
|
||||
See [RELEASE.md](RELEASE.md) for detailed release process documentation.
|
||||
|
||||
## Architecture
|
||||
|
||||
### Core Pipeline
|
||||
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
# Release Process
|
||||
|
||||
This document describes how to create a new release of Auto Claude.
|
||||
|
||||
## Automated Release Process (Recommended)
|
||||
|
||||
We provide an automated script that handles version bumping, git commits, and tagging to ensure version consistency.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Clean git working directory (no uncommitted changes)
|
||||
- You're on the branch you want to release from (usually `main`)
|
||||
|
||||
### Steps
|
||||
|
||||
1. **Run the version bump script:**
|
||||
|
||||
```bash
|
||||
# Bump patch version (2.5.5 -> 2.5.6)
|
||||
node scripts/bump-version.js patch
|
||||
|
||||
# Bump minor version (2.5.5 -> 2.6.0)
|
||||
node scripts/bump-version.js minor
|
||||
|
||||
# Bump major version (2.5.5 -> 3.0.0)
|
||||
node scripts/bump-version.js major
|
||||
|
||||
# Set specific version
|
||||
node scripts/bump-version.js 2.6.0
|
||||
```
|
||||
|
||||
This script will:
|
||||
- ✅ Update `auto-claude-ui/package.json` with the new version
|
||||
- ✅ Create a git commit with the version change
|
||||
- ✅ Create a git tag (e.g., `v2.5.6`)
|
||||
- ⚠️ **NOT** push to remote (you control when to push)
|
||||
|
||||
2. **Review the changes:**
|
||||
|
||||
```bash
|
||||
git log -1 # View the commit
|
||||
git show v2.5.6 # View the tag
|
||||
```
|
||||
|
||||
3. **Push to GitHub:**
|
||||
|
||||
```bash
|
||||
# Push the commit
|
||||
git push origin main
|
||||
|
||||
# Push the tag
|
||||
git push origin v2.5.6
|
||||
```
|
||||
|
||||
4. **Create GitHub Release:**
|
||||
|
||||
- Go to [GitHub Releases](https://github.com/AndyMik90/Auto-Claude/releases)
|
||||
- Click "Draft a new release"
|
||||
- Select the tag you just pushed (e.g., `v2.5.6`)
|
||||
- Add release notes (describe what changed)
|
||||
- Click "Publish release"
|
||||
|
||||
5. **Automated builds will trigger:**
|
||||
|
||||
- ✅ Version validation workflow will verify version consistency
|
||||
- ✅ Tests will run (`test-on-tag.yml`)
|
||||
- ✅ Native module prebuilds will be created (`build-prebuilds.yml`)
|
||||
- ✅ Discord notification will be sent (`discord-release.yml`)
|
||||
|
||||
## Manual Release Process (Not Recommended)
|
||||
|
||||
If you need to create a release manually, follow these steps **carefully** to avoid version mismatches:
|
||||
|
||||
1. **Update `auto-claude-ui/package.json`:**
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "2.5.6"
|
||||
}
|
||||
```
|
||||
|
||||
2. **Commit the change:**
|
||||
|
||||
```bash
|
||||
git add auto-claude-ui/package.json
|
||||
git commit -m "chore: bump version to 2.5.6"
|
||||
```
|
||||
|
||||
3. **Create and push tag:**
|
||||
|
||||
```bash
|
||||
git tag -a v2.5.6 -m "Release v2.5.6"
|
||||
git push origin main
|
||||
git push origin v2.5.6
|
||||
```
|
||||
|
||||
4. **Create GitHub Release** (same as step 4 above)
|
||||
|
||||
## Version Validation
|
||||
|
||||
A GitHub Action automatically validates that the version in `package.json` matches the git tag.
|
||||
|
||||
If there's a mismatch, the workflow will **fail** with a clear error message:
|
||||
|
||||
```
|
||||
❌ ERROR: Version mismatch detected!
|
||||
|
||||
The version in package.json (2.5.0) does not match
|
||||
the git tag version (2.5.5).
|
||||
|
||||
To fix this:
|
||||
1. Delete this tag: git tag -d v2.5.5
|
||||
2. Update package.json version to 2.5.5
|
||||
3. Commit the change
|
||||
4. Recreate the tag: git tag -a v2.5.5 -m 'Release v2.5.5'
|
||||
```
|
||||
|
||||
This validation ensures we never ship a release where the updater shows the wrong version.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Version Mismatch Error
|
||||
|
||||
If you see a version mismatch error in GitHub Actions:
|
||||
|
||||
1. **Delete the incorrect tag:**
|
||||
```bash
|
||||
git tag -d v2.5.6 # Delete locally
|
||||
git push origin :refs/tags/v2.5.6 # Delete remotely
|
||||
```
|
||||
|
||||
2. **Use the automated script:**
|
||||
```bash
|
||||
node scripts/bump-version.js 2.5.6
|
||||
git push origin main
|
||||
git push origin v2.5.6
|
||||
```
|
||||
|
||||
### Git Working Directory Not Clean
|
||||
|
||||
If the version bump script fails with "Git working directory is not clean":
|
||||
|
||||
```bash
|
||||
# Commit or stash your changes first
|
||||
git status
|
||||
git add .
|
||||
git commit -m "your changes"
|
||||
|
||||
# Then run the version bump script
|
||||
node scripts/bump-version.js patch
|
||||
```
|
||||
|
||||
## Release Checklist
|
||||
|
||||
Use this checklist when creating a new release:
|
||||
|
||||
- [ ] All tests passing on main branch
|
||||
- [ ] CHANGELOG updated (if applicable)
|
||||
- [ ] Run `node scripts/bump-version.js <type>`
|
||||
- [ ] Review commit and tag
|
||||
- [ ] Push commit and tag to GitHub
|
||||
- [ ] Create GitHub Release with release notes
|
||||
- [ ] Verify version validation passed
|
||||
- [ ] Verify builds completed successfully
|
||||
- [ ] Test the updater shows correct version
|
||||
|
||||
## What Gets Released
|
||||
|
||||
When you create a release, the following are built and published:
|
||||
|
||||
1. **Native module prebuilds** - Windows node-pty binaries
|
||||
2. **Electron app packages** - Desktop installers (triggered manually or via electron-builder)
|
||||
3. **Discord notification** - Sent to the Auto Claude community
|
||||
|
||||
## Version Numbering
|
||||
|
||||
We follow [Semantic Versioning (SemVer)](https://semver.org/):
|
||||
|
||||
- **MAJOR** version (X.0.0) - Breaking changes
|
||||
- **MINOR** version (0.X.0) - New features (backward compatible)
|
||||
- **PATCH** version (0.0.X) - Bug fixes (backward compatible)
|
||||
|
||||
Examples:
|
||||
- `2.5.5 -> 2.5.6` - Bug fix
|
||||
- `2.5.6 -> 2.6.0` - New feature
|
||||
- `2.6.0 -> 3.0.0` - Breaking change
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "auto-claude-ui",
|
||||
"version": "2.5.0",
|
||||
"version": "2.5.5",
|
||||
"description": "Desktop UI for Auto Claude autonomous coding framework",
|
||||
"main": "./out/main/index.js",
|
||||
"author": "Auto Claude Team",
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Version Bump Script
|
||||
*
|
||||
* Automatically bumps the version in package.json and creates a git tag.
|
||||
* This ensures version consistency between package.json and git tags.
|
||||
*
|
||||
* Usage:
|
||||
* node scripts/bump-version.js <major|minor|patch|x.y.z>
|
||||
*
|
||||
* Examples:
|
||||
* node scripts/bump-version.js patch # 2.5.5 -> 2.5.6
|
||||
* node scripts/bump-version.js minor # 2.5.5 -> 2.6.0
|
||||
* node scripts/bump-version.js major # 2.5.5 -> 3.0.0
|
||||
* node scripts/bump-version.js 2.6.0 # Set to specific version
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { execSync } = require('child_process');
|
||||
|
||||
// Colors for terminal output
|
||||
const colors = {
|
||||
reset: '\x1b[0m',
|
||||
green: '\x1b[32m',
|
||||
yellow: '\x1b[33m',
|
||||
red: '\x1b[31m',
|
||||
cyan: '\x1b[36m',
|
||||
};
|
||||
|
||||
function log(message, color = colors.reset) {
|
||||
console.log(`${color}${message}${colors.reset}`);
|
||||
}
|
||||
|
||||
function error(message) {
|
||||
log(`❌ Error: ${message}`, colors.red);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
function success(message) {
|
||||
log(`✅ ${message}`, colors.green);
|
||||
}
|
||||
|
||||
function info(message) {
|
||||
log(`ℹ️ ${message}`, colors.cyan);
|
||||
}
|
||||
|
||||
function warning(message) {
|
||||
log(`⚠️ ${message}`, colors.yellow);
|
||||
}
|
||||
|
||||
// Parse semver version
|
||||
function parseVersion(version) {
|
||||
const match = version.match(/^(\d+)\.(\d+)\.(\d+)$/);
|
||||
if (!match) {
|
||||
error(`Invalid version format: ${version}. Expected format: x.y.z`);
|
||||
}
|
||||
return {
|
||||
major: parseInt(match[1]),
|
||||
minor: parseInt(match[2]),
|
||||
patch: parseInt(match[3]),
|
||||
};
|
||||
}
|
||||
|
||||
// Bump version based on type
|
||||
function bumpVersion(currentVersion, bumpType) {
|
||||
const version = parseVersion(currentVersion);
|
||||
|
||||
switch (bumpType) {
|
||||
case 'major':
|
||||
return `${version.major + 1}.0.0`;
|
||||
case 'minor':
|
||||
return `${version.major}.${version.minor + 1}.0`;
|
||||
case 'patch':
|
||||
return `${version.major}.${version.minor}.${version.patch + 1}`;
|
||||
default:
|
||||
// Assume it's a specific version
|
||||
parseVersion(bumpType); // Validate format
|
||||
return bumpType;
|
||||
}
|
||||
}
|
||||
|
||||
// Execute shell command
|
||||
function exec(command, options = {}) {
|
||||
try {
|
||||
return execSync(command, { encoding: 'utf8', stdio: 'pipe', ...options }).trim();
|
||||
} catch (err) {
|
||||
error(`Command failed: ${command}\n${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if git working directory is clean
|
||||
function checkGitStatus() {
|
||||
const status = exec('git status --porcelain');
|
||||
if (status) {
|
||||
error('Git working directory is not clean. Please commit or stash changes first.');
|
||||
}
|
||||
}
|
||||
|
||||
// Update package.json version
|
||||
function updatePackageJson(newVersion) {
|
||||
const packagePath = path.join(__dirname, '..', 'auto-claude-ui', 'package.json');
|
||||
|
||||
if (!fs.existsSync(packagePath)) {
|
||||
error(`package.json not found at ${packagePath}`);
|
||||
}
|
||||
|
||||
const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
|
||||
const oldVersion = packageJson.version;
|
||||
|
||||
packageJson.version = newVersion;
|
||||
|
||||
fs.writeFileSync(packagePath, JSON.stringify(packageJson, null, 2) + '\n');
|
||||
|
||||
return { oldVersion, packagePath };
|
||||
}
|
||||
|
||||
// Main function
|
||||
function main() {
|
||||
const bumpType = process.argv[2];
|
||||
|
||||
if (!bumpType) {
|
||||
error('Please specify version bump type or version number.\n' +
|
||||
'Usage: node scripts/bump-version.js <major|minor|patch|x.y.z>');
|
||||
}
|
||||
|
||||
log('\n🚀 Auto Claude Version Bump\n', colors.cyan);
|
||||
|
||||
// 1. Check git status
|
||||
info('Checking git status...');
|
||||
checkGitStatus();
|
||||
success('Git working directory is clean');
|
||||
|
||||
// 2. Read current version
|
||||
const packagePath = path.join(__dirname, '..', 'auto-claude-ui', 'package.json');
|
||||
const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
|
||||
const currentVersion = packageJson.version;
|
||||
info(`Current version: ${currentVersion}`);
|
||||
|
||||
// 3. Calculate new version
|
||||
const newVersion = bumpVersion(currentVersion, bumpType);
|
||||
info(`New version: ${newVersion}`);
|
||||
|
||||
if (currentVersion === newVersion) {
|
||||
error('New version is the same as current version');
|
||||
}
|
||||
|
||||
// 4. Update package.json
|
||||
info('Updating package.json...');
|
||||
updatePackageJson(newVersion);
|
||||
success('Updated package.json');
|
||||
|
||||
// 5. Create git commit
|
||||
info('Creating git commit...');
|
||||
exec('git add auto-claude-ui/package.json');
|
||||
exec(`git commit -m "chore: bump version to ${newVersion}"`);
|
||||
success(`Created commit: "chore: bump version to ${newVersion}"`);
|
||||
|
||||
// 6. Create git tag
|
||||
info('Creating git tag...');
|
||||
exec(`git tag -a v${newVersion} -m "Release v${newVersion}"`);
|
||||
success(`Created tag: v${newVersion}`);
|
||||
|
||||
// 7. Instructions
|
||||
log('\n📋 Next steps:', colors.yellow);
|
||||
log(` 1. Review the changes: git log -1`, colors.yellow);
|
||||
log(` 2. Push the commit: git push origin <branch-name>`, colors.yellow);
|
||||
log(` 3. Push the tag: git push origin v${newVersion}`, colors.yellow);
|
||||
log(` 4. Create a GitHub release from the tag\n`, colors.yellow);
|
||||
|
||||
warning('Note: The commit and tag have been created locally but NOT pushed.');
|
||||
warning('Please review and push manually when ready.');
|
||||
|
||||
log('\n✨ Version bump complete!\n', colors.green);
|
||||
}
|
||||
|
||||
// Run
|
||||
main();
|
||||
Reference in New Issue
Block a user