<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Alfredo orozco</title>
    <description>The latest articles on Forem by Alfredo orozco (@alfreedom).</description>
    <link>https://forem.com/alfreedom</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F474229%2Fa13573d9-58c4-4c2c-832b-c73b95c007f8.jpeg</url>
      <title>Forem: Alfredo orozco</title>
      <link>https://forem.com/alfreedom</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/alfreedom"/>
    <language>en</language>
    <item>
      <title>🚀 Automate Your CHANGELOG with Git Cliff and Keep a Changelog</title>
      <dc:creator>Alfredo orozco</dc:creator>
      <pubDate>Mon, 23 Jun 2025 02:54:33 +0000</pubDate>
      <link>https://forem.com/alfreedom/automate-your-changelog-with-git-cliff-and-keep-a-changelog-2go8</link>
      <guid>https://forem.com/alfreedom/automate-your-changelog-with-git-cliff-and-keep-a-changelog-2go8</guid>
      <description>&lt;p&gt;Maintaining a &lt;strong&gt;CHANGELOG&lt;/strong&gt; in our software projects is indispensable and adds professionalism and seriousness to the product.&lt;br&gt;&lt;br&gt;
Often we forget to update our project’s CHANGELOG—either because we consider it a waste of time, because we don’t really know every change involved, or simply because we forget.&lt;/p&gt;

&lt;p&gt;A readable, well-organized changelog makes it easy to communicate changes to other developers, users, and team members we collaborate with. Additionally, it speeds up version auditing, reduces deployment errors, improves traceability in high-demand production environments, and builds trust with our code’s consumers.&lt;/p&gt;


&lt;h2&gt;
  
  
  🎯 Goal
&lt;/h2&gt;

&lt;p&gt;In this post I’ll show how to use the &lt;strong&gt;git-cliff&lt;/strong&gt; tool to automatically generate and maintain a &lt;strong&gt;CHANGELOG.md&lt;/strong&gt; file following the &lt;a href="https://keepachangelog.com/en/1.1.0/" rel="noopener noreferrer"&gt;Keep a Changelog&lt;/a&gt; standard. We’ll base everything on a commit history formatted with &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/" rel="noopener noreferrer"&gt;Conventional Commits&lt;/a&gt;, which is key for the automation to classify each change correctly.&lt;/p&gt;

&lt;p&gt;This way, we’ll end up with a clear, consistent, and always-up-to-date changelog. ✅&lt;/p&gt;


&lt;h2&gt;
  
  
  💻 Installation &amp;amp; Configuration
&lt;/h2&gt;
&lt;h3&gt;
  
  
  🔧 Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Git installed (≥ 2.20)
&lt;/li&gt;
&lt;li&gt;A commit history formatted with Conventional Commits&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  📲 Installation
&lt;/h3&gt;
&lt;h4&gt;
  
  
  macOS (Homebrew)
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;git-cliff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Linux (Linuxbrew or binary)
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;git-cliff     &lt;span class="c"&gt;# if you use Linuxbrew&lt;/span&gt;

&lt;span class="c"&gt;# or:&lt;/span&gt;

curl &lt;span class="nt"&gt;-sSL&lt;/span&gt; https://github.com/jackfirth/git-cliff/releases/download/v0.5.1/git-cliff_0.5.1_Linux_x86_64.tar.gz &lt;span class="se"&gt;\&lt;/span&gt;
  | &lt;span class="nb"&gt;tar &lt;/span&gt;xz &lt;span class="nt"&gt;-C&lt;/span&gt; ~/.local/bin
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'export PATH="$HOME/.local/bin:$PATH"'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Windows (Scoop or binary)
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="c"&gt;# With Scoop&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;scoop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;git-cliff&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Or download from Releases, unzip and add to %PATH%.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ⚙️ Basic Configuration
&lt;/h3&gt;

&lt;p&gt;Create a &lt;code&gt;cliff.toml&lt;/code&gt; file at the root of your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[git]&lt;/span&gt;
&lt;span class="py"&gt;tag_prefix&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"v"&lt;/span&gt;         &lt;span class="c"&gt;# Prefix for semantic tags&lt;/span&gt;

&lt;span class="nn"&gt;[output]&lt;/span&gt;
&lt;span class="py"&gt;file&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"CHANGELOG.md"&lt;/span&gt;
&lt;span class="py"&gt;format&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"MD"&lt;/span&gt;            &lt;span class="c"&gt;# Markdown&lt;/span&gt;

&lt;span class="nn"&gt;[sections]&lt;/span&gt;
&lt;span class="py"&gt;"🚀 Added"&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"feat"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;"🐛 Fixed"&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"fix"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;"🧰 Changed"&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"perf"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;"⚠️ Deprecated"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"chore(deprecate)"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;"🚫 Removed"&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"feat!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"BREAKING CHANGE"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;"🔒 Security"&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"fix(security)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"security"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this configuration, &lt;strong&gt;git-cliff&lt;/strong&gt; will know how to read your commits and where to group them according to the &lt;strong&gt;Keep a Changelog&lt;/strong&gt; conventions.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ Advanced Configuration
&lt;/h2&gt;

&lt;p&gt;For mature or more complex projects, you may want to align additional commit types or scopes to well-defined sections. &lt;strong&gt;git-cliff&lt;/strong&gt; lets you configure versatile grouping based on commit types and scopes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[sections]&lt;/span&gt;
&lt;span class="py"&gt;"🚀 Features"&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"feat"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;"🐛 Bug Fixes"&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"fix"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;"🧰 Improvements"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"improvement"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"perf"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;"💄 Style"&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"style"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;"📝 Docs"&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"docs"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;"⚠️ Deprecated"&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"chore(deprecate)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"feat(deprecate)"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;"🚫 Removed"&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"feat!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"BREAKING CHANGE"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;"🔒 Security"&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"fix(security)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"security"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;improvement&lt;/strong&gt;: small refinements instead of new features
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;style&lt;/strong&gt;: formatting or linting changes
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;docs&lt;/strong&gt;: anything related to documentation
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you need to add more sections, simply extend the &lt;code&gt;[sections]&lt;/code&gt; table with the keys and list of types or scopes your team uses.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏷️ Generating the CHANGELOG by Version
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create a tag&lt;/strong&gt; for the new version in your repository:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git tag v1.3.0
   git push origin &lt;span class="nt"&gt;--tags&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Generate the changelog&lt;/strong&gt; from the last two version tags:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git cliff v1.2.0..v1.3.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or, if you don’t specify tags, it will use the automatic range since the last tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git cliff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Review and commit&lt;/strong&gt; the updated changelog:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git add CHANGELOG.md
   git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"chore: release v1.3.0"&lt;/span&gt;
   git push origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🤖 CI/CD Automation
&lt;/h2&gt;

&lt;p&gt;Automating tedious tasks in your workflow saves a ton of time you can spend on higher-value activities. Automatically generating your changelog is no exception.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⚙️ GitHub Actions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;📦 Release&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;New&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;version&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(e.g.&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;1.3.0)'&lt;/span&gt;
        &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;release&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install git-cliff&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;curl -sSL https://github.com/jackfirth/git-cliff/releases/download/v0.5.1/git-cliff_0.5.1_Linux_x86_64.tar.gz \&lt;/span&gt;
            &lt;span class="s"&gt;| tar xz -C ~/.local/bin&lt;/span&gt;
          &lt;span class="s"&gt;echo "$HOME/.local/bin" &amp;gt;&amp;gt; $GITHUB_PATH&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Generate CHANGELOG and tag&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;VERSION&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.event.inputs.version }}&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;git config user.name "CI Bot 🤖"&lt;/span&gt;
          &lt;span class="s"&gt;git config user.email "ci@yourcompany.com"&lt;/span&gt;
          &lt;span class="s"&gt;git tag v${VERSION}&lt;/span&gt;
          &lt;span class="s"&gt;git cliff&lt;/span&gt;
          &lt;span class="s"&gt;git add CHANGELOG.md&lt;/span&gt;
          &lt;span class="s"&gt;git commit -m "chore: release v${VERSION}"&lt;/span&gt;
          &lt;span class="s"&gt;git push origin main --tags&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🐙 GitLab CI/CD
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;release&lt;/span&gt;

&lt;span class="na"&gt;release&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;release&lt;/span&gt;
  &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;alpine:latest&lt;/span&gt;
  &lt;span class="na"&gt;before_script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;apk add --no-cache curl git&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;curl -sSL https://github.com/jackfirth/git-cliff/releases/download/v0.5.1/git-cliff_0.5.1_Linux_x86_64.tar.gz \&lt;/span&gt;
        &lt;span class="s"&gt;| tar xz -C /usr/local/bin&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;git tag v$CI_COMMIT_REF_NAME&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;git cliff&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;git add CHANGELOG.md&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;git commit -m "chore&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;release v$CI_COMMIT_REF_NAME"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;git push origin HEAD:main --tags&lt;/span&gt;
  &lt;span class="na"&gt;only&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;tags&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;As a software engineer, I’ve seen projects with neglected change traceability: undocumented versions, teams lost among branches, and unplanned deployments—both in the companies I’ve worked for and in my own side projects.&lt;/p&gt;

&lt;p&gt;While automatic changelog generation is a powerful, versatile tool, its effectiveness depends on the team adopting and respecting commit standards—hence the importance of &lt;strong&gt;Conventional Commits&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;With &lt;strong&gt;git-cliff&lt;/strong&gt; and &lt;strong&gt;Keep a Changelog&lt;/strong&gt;, you gain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reliable automation&lt;/strong&gt;: your changelog reflects exactly the commits in your repo
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standardization&lt;/strong&gt;: all changes classified and formatted consistently
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Professionalism&lt;/strong&gt;: each release ships with a clear, audited document
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Integrate this flow into your project and CI/CD, and you’ll discover that maintaining an impeccable change history is not only simple, but adds immense value to your software’s quality and trustworthiness.&lt;/p&gt;

&lt;p&gt;Until next time!  &lt;/p&gt;

</description>
      <category>git</category>
      <category>development</category>
      <category>automation</category>
    </item>
    <item>
      <title>🚀 Generación automática de CHANGELOG con git-cliff y Convetional Commits</title>
      <dc:creator>Alfredo orozco</dc:creator>
      <pubDate>Mon, 23 Jun 2025 02:40:48 +0000</pubDate>
      <link>https://forem.com/alfreedom/generacion-automatica-de-changelog-con-git-cliff-4d92</link>
      <guid>https://forem.com/alfreedom/generacion-automatica-de-changelog-con-git-cliff-4d92</guid>
      <description>&lt;p&gt;Mantener un CHANGELOG en nuestros proyectos de software es indispensable y agrega profesionalismo y seriedad al producto. &lt;br&gt;
Muchas veces olvidamos actualizar el CHANGELOG de nuestros proyectos ya sea por que consideramos que es una pérdida de tiempo, porque no sabes en realidad de todos los cambios implicados o simplemente porque lo olvidamos.&lt;/p&gt;

&lt;p&gt;Un changelog legible y ordenado facilita comunicar los cambios a otros desarrolladores, usuarios y miembros del equipo con el que trabajamos. Además, acelera la auditoría de versiones, reduce errores en despliegues y mejora la trazabilidad en entornos de producción de alta demanda y genera confianza entre los usuarios de nuestro código.&lt;/p&gt;


&lt;h2&gt;
  
  
  🎯 Objetivo
&lt;/h2&gt;

&lt;p&gt;En este post mostraré cómo usar la herramienta &lt;strong&gt;git-cliff&lt;/strong&gt; para generar y mantener automáticamente un archivo &lt;strong&gt;CHANGELOG.md&lt;/strong&gt; siguiendo el estándar &lt;a href="https://keepachangelog.com/en/1.1.0/" rel="noopener noreferrer"&gt;Keep a Changelog&lt;/a&gt;. Todo ello se basará en un historial de commits formateados con &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/" rel="noopener noreferrer"&gt;Conventional Commits&lt;/a&gt;, lo cual es clave para que la automatización clasifique cada cambio correctamente.&lt;/p&gt;

&lt;p&gt;De esta forma obtendremos un archivo claro, uniforme y siempre actualizado. ✅&lt;/p&gt;


&lt;h2&gt;
  
  
  💻 Instalación y configuración
&lt;/h2&gt;
&lt;h3&gt;
  
  
  🔧 Requisitos previos
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Git instalado (≥ 2.20).&lt;/li&gt;
&lt;li&gt;Historial de commits limpio con Conventional Commits.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  📲 Instalación
&lt;/h3&gt;
&lt;h4&gt;
  
  
  macOS (Homebrew)
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;git-cliff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Linux (Linuxbrew o binario)
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;git-cliff     &lt;span class="c"&gt;# si usas Linuxbrew&lt;/span&gt;

&lt;span class="c"&gt;# o bien:&lt;/span&gt;

curl &lt;span class="nt"&gt;-sSL&lt;/span&gt; https://github.com/jackfirth/git-cliff/releases/download/v0.5.1/git-cliff_0.5.1_Linux_x86_64.tar.gz &lt;span class="se"&gt;\&lt;/span&gt;
  | &lt;span class="nb"&gt;tar &lt;/span&gt;xz &lt;span class="nt"&gt;-C&lt;/span&gt; ~/.local/bin
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'export PATH="$HOME/.local/bin:$PATH"'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Windows (Scoop o binario)
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Con Scoop&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;scoop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;git-cliff&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# O descarga desde Releases, descomprime y agrega a %PATH%.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ⚙️ Configuración básica
&lt;/h3&gt;

&lt;p&gt;Crea cliff.toml en la raíz de tu proyecto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[git]&lt;/span&gt;
&lt;span class="py"&gt;tag_prefix&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"v"&lt;/span&gt;         &lt;span class="c"&gt;# Prefijo de las etiquetas semánticas&lt;/span&gt;

&lt;span class="nn"&gt;[output]&lt;/span&gt;
&lt;span class="py"&gt;file&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"CHANGELOG.md"&lt;/span&gt;
&lt;span class="py"&gt;format&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"MD"&lt;/span&gt;            &lt;span class="c"&gt;# Markdown&lt;/span&gt;

&lt;span class="nn"&gt;[sections]&lt;/span&gt;
&lt;span class="py"&gt;"🚀 Added"&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"feat"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;"🐛 Fixed"&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"fix"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;"🧰 Changed"&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"perf"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;"⚠️ Deprecated"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"chore(deprecate)"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;"🚫 Removed"&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"feat!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"BREAKING CHANGE"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;"🔒 Security"&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"fix(security)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"security"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Con esto, git-cliff sabrá de cómo leer los commits y dónde agruparlos según las convenciones de &lt;strong&gt;Keep a Changelog&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ Configuración avanzada
&lt;/h2&gt;

&lt;p&gt;Para proyectos maduros o más complejos, tal vez necesites alinear más tipos de commits con secciones claras o con un formato definido por tu equipo de trabajo. git-cliff permite una configuración versátil para agrupar los cambios en las secciones en base a los tipos y scopes de los commits.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[sections]&lt;/span&gt;
&lt;span class="py"&gt;"🚀 Features"&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"feat"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;"🐛 Bug Fixes"&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"fix"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;"🧰 Improvements"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"improvement"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"perf"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;"💄 Style"&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"style"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;"📝 Docs"&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"docs"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;"⚠️ Deprecated"&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"chore(deprecate)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"feat(deprecate)"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;"🚫 Removed"&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"feat!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"BREAKING CHANGE"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;"🔒 Security"&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"fix(security)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"security"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;improvement: pequeños refinamientos en lugar de nuevas features.&lt;/li&gt;
&lt;li&gt;style: cambios de formato o linting.&lt;/li&gt;
&lt;li&gt;docs: todo lo relativo a documentación.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Si necesitas añadir más secciones, simplemente amplía el [sections] con la clave y la lista de tipos o scopes que uses en tu equipo.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏷️ Generar el CHANGELOG por versión
&lt;/h2&gt;

&lt;p&gt;Primero debes crear un tag para la versión en tu repositorio:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git tag v1.3.0
git push origin &lt;span class="nt"&gt;--tags&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Después, genera el changelog desde los 2 últimos tags de versionado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git cliff v1.2.0..v1.3.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;o, si no especificas los tags, se usará el rango automático desde la última etiqueta.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git cliff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Revisa que el archivo se haya actualizado correctamente y haz el commit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add CHANGELOG.md
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"chore: release v1.3.0"&lt;/span&gt;
git push origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🤖 Automatización en CI/CD
&lt;/h2&gt;

&lt;p&gt;Automatizar tareas tediosas lo más que se pueda en un flujo de trabajo, nos ahorra un montón de tiempo que podemos aprovechar para realizar otras tareas y mejorar nuestra productividad. La generación de CHANGELOG automáticamente no es la excepción.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⚙️ GitHub Actions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;📦 Release&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Nueva&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;versión&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(ej.&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;1.3.0)'&lt;/span&gt;
        &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;release&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Instalar git-cliff&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;curl -sSL https://github.com/jackfirth/git-cliff/releases/download/v0.5.1/git-cliff_0.5.1_Linux_x86_64.tar.gz \&lt;/span&gt;
            &lt;span class="s"&gt;| tar xz -C ~/.local/bin&lt;/span&gt;
          &lt;span class="s"&gt;echo "$HOME/.local/bin" &amp;gt;&amp;gt; $GITHUB_PATH&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Generar CHANGELOG y tag&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;VERSION&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.event.inputs.version }}&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;git config user.name "CI Bot 🤖"&lt;/span&gt;
          &lt;span class="s"&gt;git config user.email "ci@yourcompany.com"&lt;/span&gt;
          &lt;span class="s"&gt;git tag v${VERSION}&lt;/span&gt;
          &lt;span class="s"&gt;git cliff&lt;/span&gt;
          &lt;span class="s"&gt;git add CHANGELOG.md&lt;/span&gt;
          &lt;span class="s"&gt;git commit -m "chore: release v${VERSION}"&lt;/span&gt;
          &lt;span class="s"&gt;git push origin main --tags&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🐙 GitLab CI/CD
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;release&lt;/span&gt;

&lt;span class="na"&gt;release&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;release&lt;/span&gt;
  &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;alpine:latest&lt;/span&gt;
  &lt;span class="na"&gt;before_script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;apk add --no-cache curl git&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;curl -sSL https://github.com/jackfirth/git-cliff/releases/download/v0.5.1/git-cliff_0.5.1_Linux_x86_64.tar.gz \&lt;/span&gt;
        &lt;span class="s"&gt;| tar xz -C /usr/local/bin&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;git tag v$CI_COMMIT_REF_NAME&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;git cliff&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;git add CHANGELOG.md&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;git commit -m "chore&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;release v$CI_COMMIT_REF_NAME"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;git push origin HEAD:main --tags&lt;/span&gt;
  &lt;span class="na"&gt;only&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;tags&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Conclusiones
&lt;/h2&gt;

&lt;p&gt;Como ingeniero de software he visto proyectos descuidados en cuanto a trazabilidad de cambios: versiones sin documentación, equipos perdidos entre branches y despliegues imprevistos, y no solo en los distintos lugares en los que eh trabajado sino también en proyectos propios.&lt;/p&gt;

&lt;p&gt;Aunque la generación automática de changelogs es una herramienta muy versátil y de mucha ayuda, es necesario que el equipo adopte una cultura donde se respeten los estándares y convenciones para realizar los commits, ya que esta herramienta depende totalmente de ello utilizando &lt;strong&gt;Conventional Commits&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Con git-cliff y Keep a Changelog, obtenemos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatización fiable: tu changelog refleja exactamente los commits de tu repo.&lt;/li&gt;
&lt;li&gt;Estandarización: todos los cambios clasificados y formateados de la misma manera.&lt;/li&gt;
&lt;li&gt;Profesionalismo: cada release va acompañado de un documento legible y auditado.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Integra este flujo en tu proyecto y CI/CD, y descubrirás que mantener un historial de cambios impecable no solo es sencillo, sino que aporta un valor incalculable a la calidad y confianza de tu software. &lt;/p&gt;

&lt;p&gt;¡Hasta la próxima!&lt;/p&gt;

</description>
      <category>git</category>
      <category>automation</category>
      <category>development</category>
    </item>
  </channel>
</rss>
