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.

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:
YAMLjobs: 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
- Configure your local git: Ensure you are using Conventional Commits. Commit a change using the syntax
fix: resolve login issue. - Update your workflow: Add the "Create Release" job shown above to your pipeline.
- Trigger the release: Push to your
mainbranch. - 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: writepermissions, 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.
Work with me

CI/CD Pipeline & Docker Containerization
Ship with confidence: automated CI/CD pipelines and Docker setups so every push is tested and deployed — no more manual, error-prone releases.

AI Automation & Agentic Workflow Development
Automate the repetitive work eating your time — content pipelines, data workflows, and agentic AI tasks that run themselves.


