Skip to content

feat(changelog): add CHANGELOG.md for automated version history tracking #927

@beatrizsmerino

Description

@beatrizsmerino

feat(changelog): add CHANGELOG.md for automated version history tracking

⏱️ Estimate 📊 Priority 📏 Size 📅 Start 📅 End
4h P1 M 26-01-2026 26-01-2026

📸 Screenshots

Current Expected
N/A — This change has no visual impact. N/A — This change has no visual impact.

📝 Summary

  • Install conventional-changelog-cli and standard-version packages
  • Create .changelogrc.cjs configuration file with emoji categories
  • Create .versionrc.cjs configuration file for standard-version
  • Create version.sbt file for version tracking
  • Create GitFlow automation script
  • Add npm scripts for changelog generation and release automation
  • Generate CHANGELOG.md from commit history

💡 Why this change?

  • Project currently has no changelog to track version history
  • Automated changelog generation from Conventional Commits ensures consistency
  • standard-version automates the entire release flow (version bump + changelog + git tag)
  • GitFlow script automates merge to master/develop and push
  • Provides clear documentation of all changes for users and contributors

✅ Benefits

  • Automated changelog generation from commit messages
  • Consistent format with emoji categories for easy reading
  • Links to commits and issues in GitHub
  • Follows Conventional Commits standard
  • Automatic version bump based on commit types (feat → minor, fix → patch)
  • Automatic git tag creation
  • Full GitFlow automation with single command

📋 Steps

Phase 1: Install dependencies

npm install -D conventional-changelog-cli standard-version

Phase 2: Create changelog configuration file

  • Create .changelogrc.cjs file in project root with emoji categories configuration

Phase 3: Create standard-version configuration file

  • Create .versionrc.cjs file in project root:
module.exports = {
  "header": "",
  "bumpFiles": [
    {
      "filename": "version.sbt",
      "updater": "bin/standard-version-updater.js"
    },
    {
      "filename": "package.json",
      "type": "json"
    },
    {
      "filename": "package-lock.json",
      "type": "json"
    }
  ],
  "types": [
    { "type": "feat", "section": "✨ Features" },
    { "type": "fix", "section": "🐛 Fixes" },
    { "type": "perf", "section": "⚡ Performance" },
    { "type": "build", "section": "🚀 Build System" },
    { "type": "docs", "section": "📝 Documentation" },
    { "type": "style", "section": "🎨 Styles" },
    { "type": "refactor", "section": "🔨 Refactors" },
    { "type": "test", "section": "🧪 Tests" },
    { "type": "ci", "section": "🔧 Continuous Integration" },
    { "type": "revert", "section": "🔄 Reverts" },
    { "type": "chore", "hidden": true }
  ],
  "releaseCommitMessageFormat": "build(release): {{currentTag}}",
  "tagPrefix": ""
};

Phase 4: Create version.sbt file

  • Create version.sbt file in project root with current version:
ThisBuild / version := "X.X.X"
  • Create bin/standard-version-updater.js file:
module.exports.readVersion = contents => contents.match(/"(?<version>.*)"/u).groups.version;

module.exports.writeVersion = (_, version) => `ThisBuild / version := "${version}"\n`;

Phase 5: Create GitFlow automation script

  • Create bin/standar-version-updater-gitflow.sh file:
#!/bin/bash

# Check if there are uncommitted changes in the working directory
if ! git diff-index --quiet HEAD --; then
    echo "Error: You have uncommitted changes. Please commit or stash them."
    exit 1
fi

# Create temporal branch name to store the changes
timestamp=$(date +%Y%m%d%H%M%S)
branchTypeTemp="release"
branchNameTemp="$branchTypeTemp/$timestamp"

# Create and move to new branch
git checkout -b "$branchNameTemp"

# Run standard-version to update the changelog and the version
npm run changelog:update

# Get the new version created by standard-version
versionNew=$(node -p "require('./package.json').version")

# Function to extract major, minor, and patch numbers from a version
extract_version_parts() {
    IFS='.' read -ra PARTS <<< "$1"
    echo "${PARTS[@]}"
}

# Extract parts of the old and new versions
read -ra currentParts <<< $(extract_version_parts $versionCurrent)
read -ra newParts <<< $(extract_version_parts $versionNew)

# Determine the branch type based on version changes
if [ "${currentParts[0]}" != "${newParts[0]}" ] || [ "${currentParts[1]}" != "${newParts[1]}" ]; then
    branchType="release"
else
    branchType="hotfix"
fi

# Define the branch name based on the branch type and new version
branchName="$branchType/$versionNew"

# Check if the branch already exists
if git show-ref --verify --quiet "refs/heads/$branchName"; then
    echo "Error: Branch '$branchName' already exists."
    git checkout develop
    git tag -d "$versionNew"
    git branch -D "$branchNameTemp"
    exit 1
fi

# Rename the current branch with the branch type and the new version
git branch -m "$branchName"

# Function to perform git merge and handle errors
merge_branch() {
    git checkout $1
    git merge --no-ff "$branchName" -m "Merge branch '$branchName' into $1"
    if [ $? -ne 0 ]; then
        echo "Merge failed, please resolve conflicts manually."
        exit 1
    fi
}

# Merge into master
merge_branch master

# Push master and tags to remote
git push origin master --tags

# Merge into develop
merge_branch develop

# Push develop to remote
git push origin develop

# Delete the release/hotfix branch
git branch -D "$branchName"

# Checkout to develop or master based on the branch type
if [ "$branchType" = "release" ]; then
    git checkout develop
elif [ "$branchType" = "hotfix" ]; then
    git checkout master
fi

Phase 6: Add npm scripts

  • Add scripts to package.json:
{
  "scripts": {
    "changelog:init": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 --config .changelogrc.cjs",
    "changelog:update": "standard-version --releaseCommitMessageFormat 'build(release): {{currentTag}}'",
    "changelog:update:gitflow": "sh ./bin/standar-version-updater-gitflow.sh"
  }
}

Phase 7: Generate initial changelog

  • Run the changelog script to generate initial file:
npm run changelog:init

🧪 Tests

  • Verify CHANGELOG.md is created with all commit history
  • Verify CHANGELOG.md is generated correctly with changelog:init
  • Verify emoji categories display properly
  • Verify links to commits work
  • Verify links to issues work (if any referenced)
  • Verify changelog:update bumps version correctly
  • Verify version.sbt is updated with new version
  • Verify changelog:update:gitflow works end-to-end

📌 Notes

Scripts usage

Script Description
changelog:init Generate changelog from all commits (use for initial setup or regeneration)
changelog:update Bump version + update changelog + create git tag (use for releases)
changelog:update:gitflow Full GitFlow automation: bump + changelog + merge to master/develop + push

How standard-version works

  1. Analyzes commits since last tag
  2. Determines version bump based on commit types:
    • feat: → minor (1.0.0 → 1.1.0)
    • fix: → patch (1.0.0 → 1.0.1)
    • BREAKING CHANGE → major (1.0.0 → 2.0.0)
  3. Updates package.json, package-lock.json and version.sbt
  4. Updates CHANGELOG.md
  5. Creates commit with message build(release): X.X.X
  6. Creates git tag X.X.X

How changelog:update:gitflow works

  1. Checks for uncommitted changes
  2. Creates temporary release branch
  3. Runs changelog:update (standard-version)
  4. Detects if release (major/minor) or hotfix (patch)
  5. Renames branch to release/X.X.X or hotfix/X.X.X
  6. Merges to master with --no-ff
  7. Pushes master with tags
  8. Merges to develop
  9. Pushes develop
  10. Deletes release/hotfix branch
  11. Returns to develop or master

🔗 References

Files to modify

  • .changelogrc.cjs
  • .versionrc.cjs
  • version.sbt
  • bin/standard-version-updater.js
  • bin/standar-version-updater-gitflow.sh
  • package.json
  • CHANGELOG.md

Documentation

Metadata

Metadata

Labels

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions