mirror of
https://github.com/xtr-dev/payload-mailing.git
synced 2025-12-10 00:03:23 +00:00
Implement intelligent version calculation based on branch comparison
### 🚀 Features - Version bumping now compares source branch vs target branch versions - Calculates proper increment from version differences between branches - Applies calculated increment to target branch version for new version ### 🔧 Improvements - Replaces branch name-based versioning with actual version analysis - Shows detailed version calculation in workflow logs - Validates that source version is higher than target version - Supports increments greater than 1 (e.g., patch increases by 2) ### 🧮 Version Calculation Logic - **Target (main)**: `1.2.3`, **Source (patch/dev)**: `1.2.5` - **Calculation**: patch increased by 2, so increment = 1 - **Result**: `1.2.4` (target version + minimum needed increment) ### 📊 Enhanced Validation - Fails if no version increase detected between branches - Ensures positive increments for version calculations - Detailed logging of version comparison and calculation steps 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
97
.github/workflows/version-and-publish.yml
vendored
97
.github/workflows/version-and-publish.yml
vendored
@@ -53,21 +53,52 @@ jobs:
|
|||||||
- name: Run build
|
- name: Run build
|
||||||
run: pnpm build
|
run: pnpm build
|
||||||
|
|
||||||
- name: Determine version bump type
|
- name: Determine version bump from branch comparison
|
||||||
id: version-type
|
id: version-type
|
||||||
run: |
|
run: |
|
||||||
BRANCH_NAME="${{ github.ref_name }}"
|
# Get version from source branch (current)
|
||||||
if [[ "$BRANCH_NAME" =~ ^major/ ]]; then
|
SOURCE_VERSION=$(node -p "require('./package.json').version")
|
||||||
|
|
||||||
|
# Get version from target branch (main)
|
||||||
|
git fetch origin main
|
||||||
|
TARGET_VERSION=$(git show origin/main:package.json | node -p "JSON.parse(require('fs').readFileSync('/dev/stdin', 'utf8')).version")
|
||||||
|
|
||||||
|
echo "📊 Source branch version: $SOURCE_VERSION"
|
||||||
|
echo "📊 Target branch version: $TARGET_VERSION"
|
||||||
|
|
||||||
|
# Parse versions into components
|
||||||
|
IFS='.' read -r -a SOURCE_PARTS <<< "$SOURCE_VERSION"
|
||||||
|
IFS='.' read -r -a TARGET_PARTS <<< "$TARGET_VERSION"
|
||||||
|
|
||||||
|
SOURCE_MAJOR=${SOURCE_PARTS[0]}
|
||||||
|
SOURCE_MINOR=${SOURCE_PARTS[1]}
|
||||||
|
SOURCE_PATCH=${SOURCE_PARTS[2]}
|
||||||
|
|
||||||
|
TARGET_MAJOR=${TARGET_PARTS[0]}
|
||||||
|
TARGET_MINOR=${TARGET_PARTS[1]}
|
||||||
|
TARGET_PATCH=${TARGET_PARTS[2]}
|
||||||
|
|
||||||
|
# Determine version bump type based on what changed
|
||||||
|
if [ "$SOURCE_MAJOR" -gt "$TARGET_MAJOR" ]; then
|
||||||
echo "type=major" >> $GITHUB_OUTPUT
|
echo "type=major" >> $GITHUB_OUTPUT
|
||||||
elif [[ "$BRANCH_NAME" =~ ^minor/ ]]; then
|
echo "🚀 Major version increase detected ($TARGET_MAJOR → $SOURCE_MAJOR)"
|
||||||
|
elif [ "$SOURCE_MINOR" -gt "$TARGET_MINOR" ]; then
|
||||||
echo "type=minor" >> $GITHUB_OUTPUT
|
echo "type=minor" >> $GITHUB_OUTPUT
|
||||||
elif [[ "$BRANCH_NAME" =~ ^patch/ ]]; then
|
echo "✨ Minor version increase detected ($TARGET_MINOR → $SOURCE_MINOR)"
|
||||||
|
elif [ "$SOURCE_PATCH" -gt "$TARGET_PATCH" ]; then
|
||||||
echo "type=patch" >> $GITHUB_OUTPUT
|
echo "type=patch" >> $GITHUB_OUTPUT
|
||||||
|
echo "🐛 Patch version increase detected ($TARGET_PATCH → $SOURCE_PATCH)"
|
||||||
else
|
else
|
||||||
echo "type=none" >> $GITHUB_OUTPUT
|
echo "type=none" >> $GITHUB_OUTPUT
|
||||||
|
echo "⚠️ No version increase detected. Source version must be higher than target."
|
||||||
|
echo "Target: $TARGET_VERSION, Source: $SOURCE_VERSION"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Store versions for later use
|
||||||
|
echo "source-version=$SOURCE_VERSION" >> $GITHUB_OUTPUT
|
||||||
|
echo "target-version=$TARGET_VERSION" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Generate changelog with Claude
|
- name: Generate changelog with Claude
|
||||||
id: changelog
|
id: changelog
|
||||||
run: |
|
run: |
|
||||||
@@ -133,55 +164,81 @@ jobs:
|
|||||||
git config --global user.name "github-actions[bot]"
|
git config --global user.name "github-actions[bot]"
|
||||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
|
|
||||||
- name: Create version bump script
|
- name: Create version calculation script
|
||||||
run: |
|
run: |
|
||||||
# Create Node.js script to safely bump version
|
# Create Node.js script to calculate proper version increment
|
||||||
cat > bump-version.js << 'VERSION_SCRIPT_EOF'
|
cat > calculate-version.js << 'VERSION_SCRIPT_EOF'
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
const versionType = process.argv[2];
|
const versionType = process.argv[2];
|
||||||
|
const targetVersion = process.argv[3];
|
||||||
|
const sourceVersion = process.argv[4];
|
||||||
const packagePath = path.join(process.cwd(), 'package.json');
|
const packagePath = path.join(process.cwd(), 'package.json');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
|
// Parse versions
|
||||||
const currentVersion = packageJson.version;
|
const [targetMajor, targetMinor, targetPatch] = targetVersion.split('.').map(Number);
|
||||||
const [major, minor, patch] = currentVersion.split('.').map(Number);
|
const [sourceMajor, sourceMinor, sourcePatch] = sourceVersion.split('.').map(Number);
|
||||||
|
|
||||||
let newVersion;
|
let newVersion;
|
||||||
|
let increment;
|
||||||
|
|
||||||
switch (versionType) {
|
switch (versionType) {
|
||||||
case 'major':
|
case 'major':
|
||||||
newVersion = `${major + 1}.0.0`;
|
// Calculate major increment and reset minor/patch
|
||||||
|
increment = sourceMajor - targetMajor;
|
||||||
|
newVersion = `${targetMajor + increment}.0.0`;
|
||||||
break;
|
break;
|
||||||
case 'minor':
|
case 'minor':
|
||||||
newVersion = `${major}.${minor + 1}.0`;
|
// Keep major from target, calculate minor increment, reset patch
|
||||||
|
increment = sourceMinor - targetMinor;
|
||||||
|
newVersion = `${targetMajor}.${targetMinor + increment}.0`;
|
||||||
break;
|
break;
|
||||||
case 'patch':
|
case 'patch':
|
||||||
newVersion = `${major}.${minor}.${patch + 1}`;
|
// Keep major/minor from target, calculate patch increment
|
||||||
|
increment = sourcePatch - targetPatch;
|
||||||
|
newVersion = `${targetMajor}.${targetMinor}.${targetPatch + increment}`;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error(`Invalid version type: ${versionType}`);
|
throw new Error(`Invalid version type: ${versionType}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure increment is positive
|
||||||
|
if (increment <= 0) {
|
||||||
|
throw new Error(`Invalid increment ${increment} for ${versionType} version`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update package.json
|
||||||
|
const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
|
||||||
packageJson.version = newVersion;
|
packageJson.version = newVersion;
|
||||||
fs.writeFileSync(packagePath, JSON.stringify(packageJson, null, 2) + '\n');
|
fs.writeFileSync(packagePath, JSON.stringify(packageJson, null, 2) + '\n');
|
||||||
|
|
||||||
console.log(`${currentVersion}:${newVersion}`);
|
console.log(`${targetVersion}:${newVersion}:${increment}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error bumping version:', error.message);
|
console.error('Error calculating version:', error.message);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
VERSION_SCRIPT_EOF
|
VERSION_SCRIPT_EOF
|
||||||
|
|
||||||
- name: Bump version and create merge branch
|
- name: Calculate new version and create merge branch
|
||||||
id: prepare
|
id: prepare
|
||||||
run: |
|
run: |
|
||||||
VERSION_TYPE="${{ steps.version-type.outputs.type }}"
|
VERSION_TYPE="${{ steps.version-type.outputs.type }}"
|
||||||
|
TARGET_VERSION="${{ steps.version-type.outputs.target-version }}"
|
||||||
|
SOURCE_VERSION="${{ steps.version-type.outputs.source-version }}"
|
||||||
|
|
||||||
# Bump version using our safe Node.js script
|
# Calculate new version using target + calculated increment
|
||||||
VERSION_OUTPUT=$(node bump-version.js $VERSION_TYPE)
|
VERSION_OUTPUT=$(node calculate-version.js $VERSION_TYPE $TARGET_VERSION $SOURCE_VERSION)
|
||||||
CURRENT_VERSION=$(echo $VERSION_OUTPUT | cut -d: -f1)
|
CURRENT_VERSION=$(echo $VERSION_OUTPUT | cut -d: -f1)
|
||||||
NEW_VERSION=$(echo $VERSION_OUTPUT | cut -d: -f2)
|
NEW_VERSION=$(echo $VERSION_OUTPUT | cut -d: -f2)
|
||||||
|
INCREMENT=$(echo $VERSION_OUTPUT | cut -d: -f3)
|
||||||
|
|
||||||
|
echo "📊 Version calculation:"
|
||||||
|
echo " Target (main): $CURRENT_VERSION"
|
||||||
|
echo " Source (branch): $SOURCE_VERSION"
|
||||||
|
echo " New version: $NEW_VERSION"
|
||||||
|
echo " Increment: +$INCREMENT ($VERSION_TYPE)"
|
||||||
|
|
||||||
echo "current-version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
|
echo "current-version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
|
||||||
echo "new-version=$NEW_VERSION" >> $GITHUB_OUTPUT
|
echo "new-version=$NEW_VERSION" >> $GITHUB_OUTPUT
|
||||||
@@ -208,7 +265,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Clean up temporary files
|
# Clean up temporary files
|
||||||
rm -f bump-version.js
|
rm -f calculate-version.js
|
||||||
|
|
||||||
# Commit version bump and changes
|
# Commit version bump and changes
|
||||||
git add -A
|
git add -A
|
||||||
|
|||||||
Reference in New Issue
Block a user