<?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>DEV Community: Qumber Hussain</title>
    <description>The latest articles on DEV Community by Qumber Hussain (@qumberhussain).</description>
    <link>https://dev.to/qumberhussain</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%2F477565%2Ffe5a74b0-bb83-4e1f-bec5-e030f3af58f3.png</url>
      <title>DEV Community: Qumber Hussain</title>
      <link>https://dev.to/qumberhussain</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/qumberhussain"/>
    <language>en</language>
    <item>
      <title>How to be smart about releasing software -Semantic Release Conventional Commits and GitHub actions</title>
      <dc:creator>Qumber Hussain</dc:creator>
      <pubDate>Mon, 13 Feb 2023 09:07:45 +0000</pubDate>
      <link>https://dev.to/qumberhussain/how-to-be-smart-about-releasing-software-semantic-release-conventional-commits-and-github-actions-nl5</link>
      <guid>https://dev.to/qumberhussain/how-to-be-smart-about-releasing-software-semantic-release-conventional-commits-and-github-actions-nl5</guid>
      <description>&lt;p&gt;There are a multitude of ways to release software. In this article we will be discussing deployment of software with Semantic Release, Conventional Commits and GitHub actions. &lt;/p&gt;

&lt;p&gt;In an Agile world we &lt;em&gt;want&lt;/em&gt; to release software often. So the question becomes how do we release software in such a way that we &lt;em&gt;can&lt;/em&gt; release often, not break existing deployments and keep track of what was released - without the need for manual reporting on features implemented and bugs fixed.&lt;/p&gt;

&lt;p&gt;So how do we go about releasing and deploying this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Starting with Conventional commits
&lt;/h2&gt;

&lt;p&gt;Conventional commits are git commit messages that have a defined structure to make commits human and machine readable. Here are what a few typical commits may look like.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;feat(data): add JSON file with 1 meme entry&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;fix(data): correct the path of meme&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;build: add new script command for tests&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;feat(header): add Header component&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Each commit is prefixed with a type - &lt;code&gt;feat&lt;/code&gt;, &lt;code&gt;fix&lt;/code&gt;, &lt;code&gt;docs&lt;/code&gt;, &lt;code&gt;build&lt;/code&gt; etc - see documentation for full list. The type is followed by optional scope surrounded by parenthesis to describe the thing being worked on &lt;code&gt;feat(component-name)&lt;/code&gt;, &lt;code&gt;docs(component-name)&lt;/code&gt; etc.&lt;/p&gt;

&lt;p&gt;As a team, all developers must follow this convention in order for Semantic Release to work correctly. This is because these commits will be what get added in the release notes generated by Semantic Release.&lt;/p&gt;

&lt;p&gt;[Developers sign up for this convention typically at the start of a project]&lt;/p&gt;

&lt;h2&gt;
  
  
  Semantic Versioning
&lt;/h2&gt;

&lt;p&gt;Semantic versioning or SemVer for short is a specification that describes how software should be versioned. When you see a software version like &lt;code&gt;12.6.1&lt;/code&gt;, which is very common these days, the &lt;code&gt;12&lt;/code&gt; in this case is the MAJOR version, the &lt;code&gt;6&lt;/code&gt; the MINOR version and the &lt;code&gt;1&lt;/code&gt; a PATCH version. &lt;/p&gt;

&lt;p&gt;A MAJOR version number is incremented by 1 (usually) to describe this new version is incompatible with the previous version, so it is a major change. The MINOR version number is also incremented by 1 which describes new functionality has been added in a backwards compatible manner. The PATCH version describes, what usually are, bug fixes to the existing software version.&lt;/p&gt;

&lt;h2&gt;
  
  
  Semantic Release
&lt;/h2&gt;

&lt;p&gt;Semantic Release uses the specification designed by Semantic Versioning (SemVer) and couples that with Conventional Commits and a CI (continuous integration) environment to create fully automated releases.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fntp0in7h369q6uupsqfs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fntp0in7h369q6uupsqfs.png" alt="Example of Semantic Release in GitHub" width="800" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Example of Semantic Release in GitHub&lt;/p&gt;

&lt;h3&gt;
  
  
  Semantic Release for GitHub
&lt;/h3&gt;

&lt;p&gt;So we know that we need to use Conventional Commits, and that Semantic Releases uses those to generate releases and increment the software version. But how do releases get generated in GitHub? This is where the GitHub Semantic Release package comes in.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub actions
&lt;/h2&gt;

&lt;p&gt;GitHub Actions is a tool used for automating software development workflows, such as building, testing, and deploying code. When a workflow is triggered, GitHub Actions runs a series of steps in a virtual environment, such as running a script, checking out code, or deploying to a server. We will create a GitHub action by adding a &lt;code&gt;release.yml&lt;/code&gt; file in to the &lt;code&gt;.github/workflows&lt;/code&gt; folder in the repo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Let’s now create a barebones repository structure to demonstrate how Conventional Commits, Semantic Release and GitHub Actions all work together. Be sure to have the latest Node installed on your machine.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create new repo and clone it to your machine&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbn0jwcpqkuieta9ahq6s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbn0jwcpqkuieta9ahq6s.png" alt="Image description" width="709" height="963"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Change directory to cloned repository and initialise an NPM project&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;dev-project-2023
npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;This create a new Node project which allows us to take advantage of NPM and many packages that facilitate our development&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install Jest&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add jest
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Jest is a testing framework, setup here just as an example for the project.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Set up files&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create an &lt;code&gt;index.js&lt;/code&gt; file - this is typically where our application might start from
&lt;/li&gt;
&lt;/ol&gt;

&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;get2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;get2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;b. Create a &lt;code&gt;test.js&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;get2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./index.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Runs get2 returns 2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;get2&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Install SR and GHSR - Lets install SemanticRelease and GitHub Semantic Release packages&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add semantic-release github-semantic-release
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Create an &lt;code&gt;.releaser.json&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"plugins"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="s2"&gt;"@semantic-release/commit-analyzer"&lt;/span&gt;,
    &lt;span class="s2"&gt;"@semantic-release/release-notes-generator"&lt;/span&gt;,
    &lt;span class="s2"&gt;"@semantic-release/github"&lt;/span&gt;
  &lt;span class="o"&gt;]&lt;/span&gt;,
  &lt;span class="s2"&gt;"branches"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"main"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Create a &lt;code&gt;.release.yml&lt;/code&gt; file inside &lt;code&gt;.github/workflows&lt;/code&gt; folder&lt;br&gt;
&lt;/p&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="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;on"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&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;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;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;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v3&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;14.17&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yarn install --frozen-lockfile&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx semantic-release&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;GITHUB_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GH_TOKEN }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Secrets&lt;/p&gt;

&lt;p&gt;Secrets are encrypted variables that we use for authentication needed for the GitHub Semantic Release package to use. The secret (&lt;code&gt;secrets.GH_TOKEN&lt;/code&gt;) will contain your personal access token that you will need to generate in the settings tab of the repo. Follow the instructions here &lt;a href="https://github.com/semantic-release/github#configuration" rel="noopener noreferrer"&gt;https://github.com/semantic-release/github#configuration&lt;/a&gt;&lt;/p&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Create a new branch called &lt;code&gt;next&lt;/code&gt; off &lt;code&gt;main&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a feature branch called &lt;code&gt;feature-branch-x&lt;/code&gt; off &lt;code&gt;next&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Conventional commits&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make a change any change, lets say to the function and test file. And commit:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;feat(index): change function&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;get3&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;get3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;code&gt;test(index): change test file&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;get3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./index.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Runs get3 returns 3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;get3&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Merge feature branch back into &lt;code&gt;next&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Then do a pull request into &lt;code&gt;main&lt;/code&gt; and merge&lt;br&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4tbnk8eobeaby9ctergh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4tbnk8eobeaby9ctergh.png" alt="PR into main branch" width="800" height="218"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;See GitHub action running generating tag and release&lt;br&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fen2x8pu401alcoza0x8v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fen2x8pu401alcoza0x8v.png" alt="Image description" width="800" height="392"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;List of tags and releases&lt;/p&gt;&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv7917cwvd7wrheh7gut9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv7917cwvd7wrheh7gut9.png" alt="list of tags in GitHub" width="800" height="404"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftirvyctczhiovdtd5sg0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftirvyctczhiovdtd5sg0.png" alt="List of releases generated by Semantic Release in GitHub" width="800" height="1090"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we can see that after making several changes, how a tag is created and a subsequent release generated.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Together Semantic versioning, conventional commits, Github Semantic Release, and Github Actions form a powerful suite of tools that can help to streamline the software development process and ensure the delivery of high-quality software releases. By utilizing these tools, developers can work more efficiently, reduce the risk of errors, and focus on delivering valuable software to users.&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>security</category>
      <category>discuss</category>
    </item>
  </channel>
</rss>
