Building Version System: A GitHub Action for Automated Semantic Versioning

By sanjeev

Sanjeev kumar

July 1, 2025

Published

DevopsGitHub


How I solved a common developer pain point and built a tool that's now helping teams automate their release workflows

Version System Hero Image.png


The Problem That Started It All

Picture this: It's Friday afternoon, you're ready to deploy your latest feature, but first you need to create a new version tag. You check the latest tag (v1.2.3), calculate the next version (v1.2.4), create the tag, push it, then manually create a GitHub release. Five minutes later, you realize you forgot to update the version in three different places.

Sound familiar?

This scenario played out repeatedly in my development workflow. What should have been a simple task became a source of friction and potential errors. Re-running multiple CI/CD jobs because of random manually pushed git tags was a nightmare. Creating tags for Docker images and pushing them to different ECR accounts across environments became an operational headache. Some projects needed prefixes like dev-1.0.0, others required module-specific tags like api-gateway-1.2.3 for monorepos, and each had different Docker tagging strategies.

That's when I decided to build Version System - a GitHub Action that handles all the complexity of semantic versioning automatically.

Why Another Versioning Tool?

Before diving into development, I evaluated existing solutions. While there were several versioning actions available, each had limitations:

  • Complex configuration: Required extensive YAML setup for basic functionality

  • Limited flexibility: Couldn't handle prefixes, suffixes, or module-specific versioning

  • Monorepo gaps: Poor support for independent module versioning

  • Manual release steps: Required additional actions for GitHub release creation

I wanted something that would:

  1. Work with zero configuration for simple cases

  2. Scale gracefully for complex scenarios

  3. Handle monorepos elegantly

  4. Automate the entire release process

Building Version System: Key Design Decisions

1. Zero Configuration by Default

The action should work immediately with minimal setup:

yaml
- uses: sanjeevkumarraob/version-system@v1
  with:
    VERSION_FILE: "version.txt"

Just point it to a version file containing your base version (like 1.0.0), and it automatically calculates the next patch version based on existing tags.

2. Flexible Architecture for Complex Scenarios

While simple by default, the action needed to handle complex real-world scenarios:

Prefixed versions for environments:

yaml
- uses: sanjeevkumarraob/version-system@v1
  with:
    PREFIX: 'dev-'
    VERSION_FILE: "version.txt"
    # Outputs: dev-1.0.1, dev-1.0.2, etc.

Module-specific versioning for monorepos:

yaml
- uses: sanjeevkumarraob/version-system@v1
  with:
    MODULE: 'api-gateway'
    VERSION_FILE: "services/api-gateway/version.txt"
    # Outputs: api-gateway-1.0.1, api-gateway-1.0.2, etc.

Suffix support for pre-releases:

yaml
- uses: sanjeevkumarraob/version-system@v1
  with:
    SUFFIX: 'beta'
    VERSION_FILE: "version.txt"
    # Outputs: 1.0.1-beta, 1.0.2-beta, etc.

3. Intelligent Tag Analysis

The core algorithm analyzes existing repository tags to:

  • Find the latest relevant version based on prefix/suffix/module filters

  • Parse semantic version components (major.minor.patch)

  • Calculate the appropriate next version

  • Handle edge cases like missing tags or malformed versions

4. Integrated Release Creation

Rather than requiring separate actions, Version System optionally creates both tags and GitHub releases:

yaml
- uses: sanjeevkumarraob/version-system@v1
  with:
    VERSION_FILE: "version.txt"
    CREATE_RELEASE: true  # Creates tag + GitHub release with auto-generated notes

Technical Implementation Highlights

Python-Based Core Logic

I chose Python for the core versioning logic due to its excellent string processing capabilities and robust testing ecosystem. The main components:

  • Version Parser: Handles semantic version parsing with regex validation

  • Tag Manager: Interfaces with Git to fetch and analyze repository tags

  • Version Calculator: Implements the core logic for determining next versions

  • Security Module: Validates inputs and prevents path traversal attacks

Comprehensive Testing Strategy

With 97% test coverage, the action includes:

  • Unit tests: Individual component testing

  • Integration tests: End-to-end workflow validation

  • Edge case testing: Malformed versions, missing files, invalid inputs

  • Security testing: Input validation and sanitization

Shell Script Integration

The Python core integrates with a bash script that handles:

  • Environment variable processing

  • GitHub Actions output formatting

  • Error handling and logging

Real-World Impact and Use Cases

Since publishing to the GitHub Actions Marketplace, Version System has found adoption across various scenarios:

Enterprise Monorepos

Teams managing multiple services appreciate independent module versioning:

yaml
# Different services, different versions
api-gateway-2.1.4
user-service-1.3.2  
payment-service-3.0.1

Environment-Specific Deployments

Development teams use prefixes for environment isolation:

yaml
# Parallel versioning streams
prod-1.0.5
staging-1.0.8
dev-1.1.2

Open Source Projects

Maintainers automate their release processes:

yaml
# Automatic releases with generated notes
- name: Create Release
  uses: sanjeevkumarraob/version-system@v1
  with:
    VERSION_FILE: "version.txt"
    CREATE_RELEASE: true

Lessons Learned

1. Start Simple, Scale Gradually

The zero-configuration approach attracted initial users, while advanced features retained them as needs grew complex.

2. Documentation is Critical

GitHub Actions require clear, example-driven documentation. The README became as important as the code itself.

3. Test Coverage Builds Trust

High test coverage wasn't just good practice - it became a selling point for teams evaluating the action for production use.

4. Community Feedback Drives Features

Several features (like suffix support and security validations) came from user requests and issue reports.

Try It Yourself

Ready to automate your versioning workflow? Get started in minutes:

  1. Create a version file:

    # version.txt
    1.0.0
  2. Add to your GitHub workflow:

    yaml
    - name: Generate Version
      uses: sanjeevkumarraob/version-system@v1
      with:
        VERSION_FILE: "version.txt"
        CREATE_RELEASE: true
  3. Push and watch it work!

Resources


Building Version System taught me that the best tools solve real problems simply and scale gracefully. Sometimes the most impactful projects come from automating the small, repetitive tasks that slow us down every day.

Share This Article

Share this post

Help others discover this content by sharing it with your network