DEV Community

Cover image for First steps in semantic versioning
Julián Sánchez
Julián Sánchez

Posted on

First steps in semantic versioning

Relevant concepts

  • Commits: They’re snapshots of your entire repository at specific times. You should make new commits often, based on logical units of change. Over time, commits should tell a story of the history of your repository and how it came to be the way that it currently is. The commits also includes a lot of metadata in addition to the contents and message, like the author, timestamp and more.

  • Tags: They basically serve as a signed branch that does not permute, i.e. it always remains unchanged. It is simply an arbitrary string that points to a specific commit. A tag it’s like a name that you can use to mark a specific point in the history of a repository.

  • Releases: They’re deployable software iterations you can package and make available for a wider audience to download and use. Releases are based on Git tags, which mark a specific point in your repository's history. A tag date may be different than a release date since they can be created at different times.

  • Pull Request: They let you tell others about changes you've pushed to a branch in a repository on GitHub. Once a pull request is opened, you can discuss and review the potential changes with collaborators and add follow-up commits before your changes are merged into the base branch.

Note: The present article will be limited to explaining the meaning, usefulness, and functioning of semantic versioning; the concepts of tag and release will be explained lightly since they are not the current focus, they constitute the step that should be followed to apply semantic versioning.

Let's get started!

You have probably seen that in GitHub or GitLab projects there is a panel on the right side with a section called Releases:
editorjs-undo-home-page

If you click it, you’ll see the release information, something like this:
editorjs-undo-current-release

So, do you know what v2.0.0-rc.0 means? Well, let's look at something else before proceeding, in the home page you will find the tags label:
editorjs-undo-view-tags

Please click it, now you should see something like this:
editorjs-undo-tags

The first tag name matches the current release name. You’re now ready to understand its meaning. This notation is known as semantic versioning it refers to the version number of a project and It’s important because it says to you what changes could have been introduced in the code concerning the previous version.

As you can see, almost all tags are written in the vX.Y.Z format, with 3 numbers, and this is the semantic versioning core:

  • X (Major): It indicates a drastic change in the code. It isn’t compatible with previous code versions.
  • Y (Minor): It indicates a feature addition or feature modification, but the current code is compatible with the previous versions. Also is used when it’s necessary to mark something as deprecated.
  • Z (Patch): Generally, it’s used to fix bugs, and still is compatible with the previous code versions.

Now, how can you apply this if, for example, you are starting a project? It’s pretty simple. Let’s go to do a practical example:

  1. We’re going to create a repo in GitHub, you can name it whatever you want.
    create-repo-github

  2. The repo had been created. If you look closely, you will see that there is only one branch, the main branch.
    repo-github-main

  3. Before beginning to create commits, we need to create another branch (remember that it isn’t a good practice to send changes directly to the main branch). Then let's create the v0.1 branch (is actually v0.1.0, but when Z is zero, we can omit it from the branch name).
    repo-github-branches

    Well, this is a good point to explain additional adjusts:

    a. All branches must be created from the main branch.
    b. The v0.1 branch is used because will be the first release, and probably not a stable version, it will need more adjusts.
    c. All tags between 1.0.0 and 1.9.9 should be contained in the v1.0.0 (or v1.0) branch, all tags between 2.0.0 and 2.9.9 should be contained in the v2.0.0 (or v2.0) branch, and so on.
    d. Probably the v0.1 branch will have only one tag, the v0.1, and this is right because is our first version, so we’re implementing the initial functionality of the project.
    e. When the changes introduced in the current branch are ready, you must create a PR to merge with the main branch.

  4. Now, we’re going to create commits implementing the transactional system features:

    a. Install the initial project configuration and its dependencies.
    b. Add the login/signup component.
    c. Implement the allowed transactions.
    d. Add the user roles.
    e. Limit the user permissions.
    f. Implement a public dashboard to display transactions in real-time.
    g. Implement methods to ensure transaction integrity.

    Now, in the v0.1 branch we have the previous commits:
    repo-github-with-new-commits
    repo-github-commits

  5. As these features will be our first project version, let’s create the tag with its version number, in this case, we’ll create the v0.1 tag to establish the project version.

    git tag -a v0.1 -m "Initial release"
    
    git push origin --tags
    

    If you see the GitHub repo, now there’s a tag, the one we just created.
    repo-github-view-tags
    repo-github-tags

  6. With this first version, we can create the PR to merge the v0.1 branch with the main branch:

    repo-github-create-pr

  7. Now, if you return to the main branch, you’ll see something like the following, so let’s create our first release.

    repo-github-releases

    repo-github-create-releases

The process to create new tags and publish releases is very similar to the one seen above, e.g., if we wanted to solve a security problem in version 0.1, we would create commits to solve it on the v0.1 branch, then we could create the v0.1.1 tag, create again a PR to merge with the main branch and finally create the release with this version more stable than the previous one.

In some projects, you can see releases like v1.0.3-alpha, v1.0.3-beta. Do you know what is this? These additional words are stability indicators, and they use greek letters, so alpha < beta, i.e., beta is more stable than alpha.

In some projects, release candidates are also used, which are branches that are sufficiently solid, or that want to establish enough solidity when the release is created (which will probably be used by end-users), it will have as few errors as possible.

Surely this is not the only way to use semantic versioning in projects, so far I think it is a good way to do it and it’s easy to understand and share, there may be better ways to do it so, why don't you tell me how you do it or what you would improve to the current one?

📔 This information may be of interest to you:

Top comments (0)