Back to Blog
Lesson 51 of the CI/CD: Continuous Integration from Scratch course
DevOpsAugust 26, 20263 min read

Automating Releases: Versioning and Changelogs in CI/CD

Learn to automate software releases by implementing semantic versioning and generating automated release notes directly within your CI/CD pipeline.

ci/cdgithub actionsautomationdevopssemantic versioningreleases
A close-up of CDs and disks on a desk, featuring hands in a tech environment.

Previously in this course, we covered production-deployment-automating-secure-cd-pipelines and automating-deployments-with-ci-cd-a-github-actions-guide. While we have successfully moved code into production, we have been doing so without a clear versioning strategy or documentation of what actually changed. This lesson adds automation to your release lifecycle, ensuring that every time you ship, you have a consistent version number and a clear, machine-generated changelog.

Semantic Versioning: The Foundation of Releases

Semantic Versioning (SemVer) is a three-part version number: MAJOR.MINOR.PATCH (e.g., 1.4.2). This is not just a random sequence; it tells your users exactly how "breaking" a change is:

  • MAJOR: Incremented for incompatible API changes.
  • MINOR: Incremented for adding functionality in a backwards-compatible manner.
  • PATCH: Incremented for backwards-compatible bug fixes.

By adopting this, you provide a clear signal to anyone using your software. In our pipeline, we will use semantic-release or similar GitHub Actions to infer the next version number based on your commit messages.

Generating Automated Release Notes

Manually writing changelogs is error-prone and often forgotten. Automation allows us to extract information from the commit history. By enforcing a standard like Conventional Commits, we can categorize commits into "Features," "Fixes," and "Breaking Changes," allowing tools to build a summary for us automatically.

Worked Example: Automating Versioning with GitHub Actions

To implement this, we will use the marvinpinto/action-automatic-releases (or a similar stable action) to create a GitHub Release whenever we push a tag or merge to main.

Add this job to your existing .github/workflows/main.yml:

YAML
jobs:
  release:
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v4
      - name: Create Release
        uses: marvinpinto/action-automatic-releases@latest
        with:
          repo_token: "${{ secrets.GITHUB_TOKEN }}"
          automatic_release_tag: "latest"
          prerelease: false
          title: "Production Release"

In a professional setting, you would typically use a tool that reads your commit history to calculate the version. If your commit message starts with fix:, the tool increments the PATCH number. If it starts with feat:, it increments the MINOR number.

Hands-on Exercise

  1. Configure your local git: Ensure you are using Conventional Commits. Commit a change using the syntax fix: resolve login issue.
  2. Update your workflow: Add the "Create Release" job shown above to your pipeline.
  3. Trigger the release: Push to your main branch.
  4. Verify: Navigate to the "Releases" tab in your GitHub repository and verify that a new release has been created with your commit message included in the logs.

Common Pitfalls

  • Forgetting permissions: Ensure your GitHub Action has contents: write permissions, otherwise, it will fail when trying to create the release tag.
  • Dirty Git history: If your commit messages are messy (e.g., "fixed stuff", "typo"), automated changelogs will be unreadable. Enforce a commit linting policy early.
  • Ignoring the tag: If your automation creates a tag, ensure your deployment job is configured to trigger on that tag, not just on any push to main.

FAQ

Why use automation instead of manual tagging? Manual tagging is subject to human error—you might skip a version or mislabel a breaking change. Automation ensures 100% consistency across your releases.

Do I have to use Conventional Commits? Technically, no, but it is highly recommended. Without a structured format, automated tools cannot reliably categorize your changes into "Features" vs "Fixes."

Recap

We have moved from manual deployment to a structured release process. By using versioning standards and automation for our changelogs, we ensure that every release is documented, versioned, and audit-ready. This level of rigor is what separates hobby projects from production-grade engineering environments.

Up next: We will tackle handling-large-files-in-ci, where we'll learn how to optimize our pipelines when dealing with binaries and large assets.

Similar Posts