<?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: Bruno Sartori</title>
    <description>The latest articles on DEV Community by Bruno Sartori (@brunosartori).</description>
    <link>https://dev.to/brunosartori</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%2F2005306%2F02644f25-c8a2-45f0-a8d2-5128c5a86cde.jpeg</url>
      <title>DEV Community: Bruno Sartori</title>
      <link>https://dev.to/brunosartori</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/brunosartori"/>
    <language>en</language>
    <item>
      <title>How to Set Up Dependabot for Automated Dependency Management</title>
      <dc:creator>Bruno Sartori</dc:creator>
      <pubDate>Sat, 16 Nov 2024 13:49:35 +0000</pubDate>
      <link>https://dev.to/brunosartori/how-to-set-up-dependabot-for-automated-dependency-management-59eh</link>
      <guid>https://dev.to/brunosartori/how-to-set-up-dependabot-for-automated-dependency-management-59eh</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Dependabot is a tool created by GitHub to automate the dependency management of your project. It monitors your project’s dependencies and automatically creates pull requests to update then when needed. Dependabot also highlights security vulnerabilities in your project’s dependencies, helping you to prevent potential risks in your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use Dependabot?
&lt;/h2&gt;

&lt;p&gt;Here are some key benefits of using Dependabot:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Regular Automated Updates:&lt;/strong&gt; Dependabot consistently reviews for vulnerable dependencies and sends pull requests (PRs) to keep them up to date.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced Productivity:&lt;/strong&gt; Streamlining the management of dependencies allows your team to dedicate their efforts to developing features of constantly monitoring package changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ensuring Compatibility:&lt;/strong&gt; With Dependabots feature to test updates in a setup using pull requests (PR) you can confirm if the changes are compatible, before integrating them.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to set up Dependabot
&lt;/h2&gt;

&lt;p&gt;Follow the steps above to set up Dependabot in your project:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Enable Dependabot for Your Repository
&lt;/h3&gt;

&lt;p&gt;To begin using Dependabot, navigate to the repository where you want to enable it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the &lt;strong&gt;"Security"&lt;/strong&gt; tab in your repository.&lt;/li&gt;
&lt;li&gt;In the left sidebar, click &lt;strong&gt;"Dependabot Alerts"&lt;/strong&gt; or &lt;strong&gt;"Dependabot Security Updates"&lt;/strong&gt; (if available).&lt;/li&gt;
&lt;li&gt;Enable Dependabot by clicking &lt;strong&gt;"Enable security updates"&lt;/strong&gt; if it's not already turned on.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once enabled, Dependabot will begin monitoring your project for dependency updates and security vulnerabilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Add a Dependabot Configuration File
&lt;/h3&gt;

&lt;p&gt;To customize how Dependabot operates, you can create a configuration file (&lt;code&gt;dependabot.yml&lt;/code&gt;). This file defines which dependencies Dependabot should monitor and how often it should check for updates.&lt;/p&gt;

&lt;p&gt;Here’s how to create the &lt;code&gt;dependabot.yml&lt;/code&gt; file:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In your repository, navigate to the root directory.&lt;/li&gt;
&lt;li&gt;Create a new folder called &lt;code&gt;.github&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Inside the &lt;code&gt;.github&lt;/code&gt; folder, create a file named &lt;code&gt;dependabot.yml&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, let’s configure it. Below is an example of a &lt;code&gt;dependabot.yml&lt;/code&gt; file for a JavaScript project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
&lt;span class="na"&gt;updates&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;package-ecosystem&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;npm"&lt;/span&gt; &lt;span class="c1"&gt;# Type of dependencies (npm, pip, bundler, etc.)&lt;/span&gt;
    &lt;span class="na"&gt;directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/"&lt;/span&gt;           &lt;span class="c1"&gt;# Directory where the dependencies file is located&lt;/span&gt;
    &lt;span class="na"&gt;schedule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;daily"&lt;/span&gt;       &lt;span class="c1"&gt;# Frequency of checking updates (daily, weekly, monthly)&lt;/span&gt;
    &lt;span class="na"&gt;ignore&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;dependency-name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lodash"&lt;/span&gt;  &lt;span class="c1"&gt;# Ignore specific dependencies (optional)&lt;/span&gt;
        &lt;span class="na"&gt;versions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;4.17.15"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Key Components:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;package-ecosystem&lt;/code&gt;: Specify the type of dependencies you’re using (e.g., npm, pip, gradle).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;directory&lt;/code&gt;: The location of your dependencies file (like &lt;code&gt;package.json&lt;/code&gt;, &lt;code&gt;requirements.txt&lt;/code&gt;, etc.).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;schedule&lt;/code&gt;: Choose Dependabot’s update check frequency (daily, weekly, or monthly).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ignore&lt;/code&gt;: List any dependencies you want Dependabot to skip for updates.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Configure Additional Settings (Optional)
&lt;/h3&gt;

&lt;p&gt;Dependabot also allows you to configure additional settings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Versioning Rules&lt;/strong&gt;: You can specify versioning constraints to control which versions of a dependency should be updated.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security Updates Only&lt;/strong&gt;: If you only want Dependabot to notify you of security-related updates, you can configure it to create PRs exclusively for security vulnerabilities.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, to restrict Dependabot to only update dependencies with security vulnerabilities, you can add the following to your configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;security-updates-only&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Reviewing and Merging Pull Requests
&lt;/h3&gt;

&lt;p&gt;Once Dependabot detects an available update, it will automatically open a pull request. The PR will include information about the update, such as the version number and a summary of changes. You can review the changes, run your tests, and merge the PR if everything looks good.&lt;/p&gt;

&lt;p&gt;You can also configure automatic merging for Dependabot PRs by enabling the auto-merge feature in your repository settings or through your Dependabot configuration.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Monitor and Manage Dependabot Activity
&lt;/h3&gt;

&lt;p&gt;You can monitor all of Dependabot’s activity and updates through the GitHub &lt;strong&gt;Security&lt;/strong&gt; tab. It will provide an overview of open PRs, dependency updates, and security alerts. You can also configure notifications to receive alerts directly in your GitHub dashboard.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Use Cases for Dependabot
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Updating npm Packages in JavaScript Projects&lt;/strong&gt;: Dependabot regularly checks the &lt;code&gt;package.json&lt;/code&gt; and &lt;code&gt;package-lock.json&lt;/code&gt; files and opens PRs to keep dependencies up to date.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintaining Python Dependencies&lt;/strong&gt;: For Python projects using &lt;code&gt;requirements.txt&lt;/code&gt;, Dependabot helps ensure your dependencies are current and secure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Managing Ruby Gems&lt;/strong&gt;: Dependabot works with &lt;code&gt;Gemfile&lt;/code&gt; and &lt;code&gt;Gemfile.lock&lt;/code&gt; for Ruby projects to automate gem updates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring Dockerfiles&lt;/strong&gt;: Dependabot can also be used to update Docker dependencies listed in Dockerfiles.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Best Practices for Using Dependabot
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Test Updates Thoroughly&lt;/strong&gt;: Ensure that any dependency updates are thoroughly tested in your CI/CD pipeline before merging to prevent breaking changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitor Security Alerts&lt;/strong&gt;: Act on Dependabot's security alerts promptly to patch vulnerabilities as soon as possible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ignore Unnecessary Updates&lt;/strong&gt;: If certain dependencies don't require frequent updates (e.g., if they rarely change or are pinned for specific reasons), consider adding them to the ignore list to reduce noise.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Dependabot simplifies dependency management by automatically updating and securing your project whenever necessary. This guide's instructions will help you configure Dependabot in your GitHub repositories for monitoring and updating dependencies, allowing you to receive automated pull requests and security notifications via Dependabot’s services to keep your project secure and efficient.&lt;/p&gt;

&lt;p&gt;Incorporating Dependabot into your workflow is a choice to boost productivity and reduce the risk of security vulnerabilities in your codebase.&lt;/p&gt;

</description>
      <category>dependabot</category>
      <category>github</category>
      <category>softwaredevelopment</category>
      <category>git</category>
    </item>
    <item>
      <title>How to add Structured Data Markup to your Website</title>
      <dc:creator>Bruno Sartori</dc:creator>
      <pubDate>Wed, 06 Nov 2024 14:21:19 +0000</pubDate>
      <link>https://dev.to/brunosartori/how-to-add-structured-data-markup-to-your-website-14og</link>
      <guid>https://dev.to/brunosartori/how-to-add-structured-data-markup-to-your-website-14og</guid>
      <description>&lt;p&gt;&lt;em&gt;by &lt;a href="https://www.linkedin.com/in/bruno-sartori-dev" rel="noopener noreferrer"&gt;Bruno Sartori&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Search Engine Optimization (SEO) is crucial for any business who wants to be successful in the online world. One powerful tool that has emerged in recent years is structured data markup, which enables search engines to better understand and interpret website’s content. This leads to better visibility and more informative displays in search results. In this article, we’ll dive into what structured data markup is, its relevance for SEO, and how to implement it on your website.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Structured Data Markup and Why is it Important for SEO?
&lt;/h2&gt;

&lt;p&gt;Structured Data Markup is a standardized way to provide metadata about a webpage’s content. By utilizing structured data, search engines like Google can better grasp the context of your page and showcase it more clearly in search results. Often represented in JSON-LD format, structured data can describe a variety of content types like articles, recipes, videos, and products.&lt;/p&gt;

&lt;p&gt;Implementing structured data can result in rich results, which enhance your search listing by displaying additional details like images, ratings, and prices. These rich results are more visually appealing and can greatly increase your click-through rate (CTR) and user engagement.&lt;/p&gt;

&lt;p&gt;For example, according to &lt;a href="https://developers.google.com/search/docs/appearance/structured-data/intro-structured-data#why" rel="noopener noreferrer"&gt;Google Search Central&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rotten Tomatoes applied structured data to &lt;strong&gt;100,000&lt;/strong&gt; pages and saw a &lt;strong&gt;25% increase&lt;/strong&gt; in CTR for those pages.&lt;/li&gt;
&lt;li&gt;The Food Network enabled search features on &lt;strong&gt;80%&lt;/strong&gt; of its pages, leading to a &lt;strong&gt;35% boost&lt;/strong&gt; in visits.&lt;/li&gt;
&lt;li&gt;Rakuten noted users spent &lt;strong&gt;1.5x more time&lt;/strong&gt; on pages with structured data and had a &lt;strong&gt;3.6x higher&lt;/strong&gt; interaction rate on AMP pages with search features.&lt;/li&gt;
&lt;li&gt;Nestlé reported an &lt;strong&gt;82% increase&lt;/strong&gt; in CTR for pages that appeared as rich results compared to non-rich result pages.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Key Benefits of Structured Data:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Improved Search Appearance&lt;/strong&gt;: Structured data enhances your site's appearance in search results with rich snippets that include additional content like reviews, recipes, and events.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Higher CTR&lt;/strong&gt;: Rich snippets attract more clicks as users can preview more information directly in the search results.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimized for Voice Search&lt;/strong&gt;: Structured data is key for voice search, allowing search engines to provide more accurate responses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better Content Relevance&lt;/strong&gt;: Helps search engines understand and categorize your content, potentially improving your rankings.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common Types of Structured Data
&lt;/h2&gt;

&lt;p&gt;Here are some widely used types of structured data that help optimize SEO:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Product Data&lt;/strong&gt;: For eCommerce websites, it displays product details like pricing, availability, and customer reviews.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Article&lt;/strong&gt;: Ensures news articles or blog posts appear in search results with added features like images and publication dates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Breadcrumbs&lt;/strong&gt;: Shows the structure of the site, improving navigation for users.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event&lt;/strong&gt;: Highlights details about upcoming events, including time and location.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recipe&lt;/strong&gt;: Ideal for food-related content, allowing users to see images, preparation times, and reviews.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Video&lt;/strong&gt;: Makes video content stand out with thumbnails, play times, and other visual enhancements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FAQ&lt;/strong&gt;: Displays frequently asked questions directly in search results, making it easier for users to get quick answers.&lt;/li&gt;
&lt;/ul&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%2F1zpkfi3gcugwagx7iej5.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%2F1zpkfi3gcugwagx7iej5.png" alt="Google's Recipe Strucrtured Data Markup result" width="715" height="319"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Implement Structured Data on Your Website
&lt;/h2&gt;

&lt;p&gt;Structured data can be added using several formats, including JSON-LD, Microdata, and RDFa. JSON-LD is often the preferred method as it's simpler to implement and maintain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Steps for Implementing Structured Data:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Select the Structured Data Type&lt;/strong&gt;: Choose the type of structured data that fits your content. Google’s &lt;a href="https://www.google.com/webmasters/markup-helper/" rel="noopener noreferrer"&gt;Structured Data Markup Helper&lt;/a&gt; is a helpful resource for picking the right schema.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generate the Markup&lt;/strong&gt;: Once you have the type of data you need, generate the JSON-LD code using tools like Google’s &lt;a href="https://search.google.com/structured-data/testing-tool/" rel="noopener noreferrer"&gt;Structured Data Testing Tool&lt;/a&gt; or &lt;a href="https://schema.org/" rel="noopener noreferrer"&gt;Schema.org&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Add the Markup to Your Website&lt;/strong&gt;: Insert the generated JSON-LD code into the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; section or body of your HTML. For example, here’s a JSON-LD snippet for a recipe page:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"application/ld+json"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@context&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;https://schema.org/&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Recipe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Chocolate Chip Cookies&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;author&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Person&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;datePublished&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2024-09-17&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A delicious chocolate chip cookie recipe.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;recipeIngredient&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1 cup sugar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2 cups flour&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1 cup chocolate chips&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;recipeInstructions&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Preheat oven to 350 degrees F.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Mix sugar, flour, and chocolate chips.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bake for 10-12 minutes.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aggregateRating&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;AggregateRating&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ratingValue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;5&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;reviewCount&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;30&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="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Test the Markup&lt;/strong&gt;: Before going live, use tools like Google’s Rich Results Test to check for any errors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Monitor Performance&lt;/strong&gt;: After implementation, track how your structured data is performing in Google Search Console. It provides data on what structured data is being used and any issues that may arise.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Best Practices for Structured Data:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use Valid Schema&lt;/strong&gt;: Always ensure that your structured data follows the standards laid out by &lt;a href="https://schema.org/" rel="noopener noreferrer"&gt;Schema.org&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Relevance is Key&lt;/strong&gt;: Only add structured data that accurately represents your content. Avoid manipulating search results with irrelevant data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Regular Updates&lt;/strong&gt;: Keep your structured data up-to-date, especially for time-sensitive elements like prices or product availability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid Overloading&lt;/strong&gt;: Focus on including structured data that enhances the user experience without overstuffing your content.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Structured data markup is an essential part of SEO strategy today. It helps search engines better understand and present your content, increasing your chances of appearing in rich results. By implementing structured data correctly and following best practices, you can improve your site’s visibility, increase traffic, and enhance its overall performance in search results.&lt;/p&gt;

&lt;p&gt;If you're looking to elevate your website’s SEO, incorporating structured data is a crucial step!&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://developers.google.com/search/docs/appearance/structured-data/search-gallery" rel="noopener noreferrer"&gt;https://developers.google.com/search/docs/appearance/structured-data/search-gallery&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developers.google.com/search/docs/appearance/structured-data/intro-structured-data" rel="noopener noreferrer"&gt;https://developers.google.com/search/docs/appearance/structured-data/intro-structured-data&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developers.google.com/search/docs/appearance/structured-data" rel="noopener noreferrer"&gt;https://developers.google.com/search/docs/appearance/structured-data&lt;/a&gt;&lt;/p&gt;

</description>
      <category>structureddatamarkup</category>
      <category>google</category>
      <category>seo</category>
      <category>richresults</category>
    </item>
    <item>
      <title>How to create and publish an NPM unscoped and scoped package with Typescript</title>
      <dc:creator>Bruno Sartori</dc:creator>
      <pubDate>Fri, 20 Sep 2024 23:10:58 +0000</pubDate>
      <link>https://dev.to/brunosartori/how-to-create-and-publish-an-npm-unscoped-and-scoped-package-with-typescript-b1e</link>
      <guid>https://dev.to/brunosartori/how-to-create-and-publish-an-npm-unscoped-and-scoped-package-with-typescript-b1e</guid>
      <description>&lt;p&gt;&lt;em&gt;by &lt;a href="https://www.linkedin.com/in/bruno-sartori-dev" rel="noopener noreferrer"&gt;Bruno Sartori&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Have &lt;a href="https://nodejs.org/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; installed, a good option for managing multiple versions of Node.js on your PC is to install it via &lt;a href="https://github.com/nvm-sh/nvm" rel="noopener noreferrer"&gt;NVM&lt;/a&gt;. It also has a &lt;a href="https://github.com/coreybutler/nvm-windows" rel="noopener noreferrer"&gt;Windows version&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;An account created on &lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;https://www.npmjs.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1. Initialize a new Project
&lt;/h3&gt;

&lt;p&gt;Create a new directory and initialize NPM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create an initial &lt;code&gt;package.json&lt;/code&gt; file&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Install dependencies
&lt;/h3&gt;

&lt;p&gt;The dependencies we will be using are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;typescript&lt;/strong&gt;: TypeScript adds optional types to JavaScript that support tools for large-scale JavaScript applications for any browser, for any host, on any OS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;@types/node&lt;/strong&gt;: TypeScript definitions for Node.js&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ts-node&lt;/strong&gt;: a TypeScript execution engine and REPL for Node.js. It JIT transforms TypeScript into JavaScript, enabling you to directly execute TypeScript on Node.js without precompiling.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use the following command to install them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add &lt;span class="nt"&gt;-D&lt;/span&gt; typescript @types/node ts-node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After finish installing the dependencies, initialize TypeScript with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx tsc &lt;span class="nt"&gt;--init&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a default &lt;code&gt;tsconfig.json&lt;/code&gt; file.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Write your first TypeScript code
&lt;/h3&gt;

&lt;p&gt;Create a &lt;code&gt;src&lt;/code&gt; folder and a file named &lt;code&gt;index.ts&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;src
&lt;span class="nb"&gt;cd &lt;/span&gt;src
&lt;span class="nb"&gt;touch &lt;/span&gt;index.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside your &lt;code&gt;index.ts&lt;/code&gt; file, write a simple function&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;triangleArea&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;base&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&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;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;triangleArea&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Building the Project
&lt;/h3&gt;

&lt;p&gt;In your &lt;code&gt;tsconfig.json&lt;/code&gt; file:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;update the &lt;code&gt;outputDir&lt;/code&gt; property to your desired build directory&lt;/li&gt;
&lt;li&gt;update the &lt;code&gt;include&lt;/code&gt; property so that TypeScript does not compile undesired files to your build directory&lt;/li&gt;
&lt;li&gt;update the &lt;code&gt;exclude&lt;/code&gt; property so that TypeScript skip them when resolving &lt;code&gt;include&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"compilerOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"outDir"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./dist"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"include"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"exclude"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"node_modules"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dist"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update your &lt;code&gt;package.json&lt;/code&gt; file to setup your build script&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Setting things up for publishing
&lt;/h3&gt;

&lt;p&gt;In your &lt;code&gt;package.json&lt;/code&gt; file, use the &lt;code&gt;files&lt;/code&gt; property to set the directory that should be included in your NPM release and the &lt;code&gt;main&lt;/code&gt; and &lt;code&gt;types&lt;/code&gt; property to determine the entry point of your project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dist/index.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dist/index.d.ts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"files"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"dist"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't forget to build your project before publishing, you can configure NPM's &lt;code&gt;prepublishOnly&lt;/code&gt; script in your &lt;code&gt;package.json&lt;/code&gt; to avoid forgetting to build every time you need to publish your package&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"prepublishOnly"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run build"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. Publishing to NPM
&lt;/h3&gt;

&lt;p&gt;Before publishing, login to NPM&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Publish your package&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm publish
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congratulations, you have successfully created your first NPM package! To see your published package visit &lt;code&gt;https://npmjs.com/package/your-package-name&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After the first publish, be aware that NPM does not let you publish your package if you don't increment your version in &lt;code&gt;package.json&lt;/code&gt; . A good way to always maintain your version updated is to set up a &lt;strong&gt;pre-commit hook&lt;/strong&gt; that remembers you to &lt;strong&gt;increment your version when committing your files&lt;/strong&gt;, you can read more about this &lt;a href="https://medium.com/@brunosartori.dev/using-husky-to-help-you-avoid-f-ing-up-semantic-versioning-8098eb3d74d1" rel="noopener noreferrer"&gt;&lt;strong&gt;HERE&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Publish your package under an Organization Scope
&lt;/h3&gt;

&lt;p&gt;Publishing an NPM package under an organization scope can be very advantageous to avoid naming collisions, creating private packages, etc. &lt;/p&gt;

&lt;h3&gt;
  
  
  7.1. Create an Organization on NPM
&lt;/h3&gt;

&lt;p&gt;To create an organization scoped NPM package, first you need to create an organization. Go to &lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;https://www.npmjs.com&lt;/a&gt;, click in the profile icon on the right top side of the screen and click in &lt;code&gt;+ Add Organization&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy9l0d04sl9n1yrkapw0l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy9l0d04sl9n1yrkapw0l.png" alt="Add Organization button on npmjs.com" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Type the name of your organization and click in the &lt;code&gt;Create&lt;/code&gt; button on Free option, which allows you to create unlimited public packages, or, if you want to create private packages, you can buy the private version.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjdzk0xmxtvcdg3o6jsuh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjdzk0xmxtvcdg3o6jsuh.png" alt="Creating a new free organization on npmjs.com - step 1" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the next screen, you can invite other people to your organization by typing their npm username or email. We will skip this step by clicking in the button &lt;code&gt;Skip this for now&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsas0ii1vvwvnzyqzs2he.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsas0ii1vvwvnzyqzs2he.png" alt="Creating a new free organization on npmjs.com — step 2" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After this step, the organization will be successfully created.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpaoatme81v754rt6kdvd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpaoatme81v754rt6kdvd.png" alt="New organization successfully created" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  7.2. Create an organization scoped NPM package
&lt;/h3&gt;

&lt;p&gt;To create an organization scoped NPM package, after creating the folder for your new project, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm init &lt;span class="nt"&gt;--scope&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;@your-organization-name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Continue answering the npm prompts to create a &lt;code&gt;package.json&lt;/code&gt; file. You should create the package name with the following format: &lt;code&gt;@your-organization-name/package-name&lt;/code&gt;. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;@bsartori/weeb-logger
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: If you already have a NPM project created you don’t need to do &lt;code&gt;npm init&lt;/code&gt; again, just change the name property in your &lt;code&gt;package.json&lt;/code&gt; file to &lt;code&gt;@your-organization-name/package-name&lt;/code&gt; format and you are good to go.&lt;/p&gt;

&lt;h3&gt;
  
  
  7.3. Publish your organization scoped NPM package
&lt;/h3&gt;

&lt;p&gt;Don’t forget to login on NPM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then publish your package passing the access privileges for the package depending of the organization type you have created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm publish &lt;span class="nt"&gt;--access&lt;/span&gt; public
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To see your public package, visit &lt;code&gt;https://npmjs.com/package/@your-organization-name/package-name&lt;/code&gt;, for example: &lt;a href="https://www.npmjs.com/package/@bsartori/weeb-logger" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/@bsartori/weeb-logger&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzxfjhgpxbhedvheal2w8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzxfjhgpxbhedvheal2w8.png" alt="NPM package published over an organization scope" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Concluding the process of creating and publishing an NPM package, especially using TypeScript, is a crucial step for developers who want to share their solutions with the community or for private use in their projects. By following this guide, you have learned how to set up your development environment, create a package using best practices, and publish it on NPM, ensuring it is globally accessible. Additionally, exploring publishing under an organization scope provides an extra layer of control and organization for companies and teams. With these skills, you are now equipped to create, manage, and distribute packages efficiently, while maintaining a continuous and automated workflow for future releases.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.npmjs.com/creating-and-publishing-unscoped-public-packages" rel="noopener noreferrer"&gt;https://docs.npmjs.com/creating-and-publishing-unscoped-public-packages&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.npmjs.com/creating-and-publishing-scoped-public-packages" rel="noopener noreferrer"&gt;https://docs.npmjs.com/creating-and-publishing-scoped-public-packages&lt;/a&gt;&lt;/p&gt;

</description>
      <category>npm</category>
      <category>typescript</category>
      <category>node</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Mastering NPM Link: Simplifying Local Dependency Management</title>
      <dc:creator>Bruno Sartori</dc:creator>
      <pubDate>Sat, 14 Sep 2024 23:21:47 +0000</pubDate>
      <link>https://dev.to/brunosartori/mastering-npm-link-simplifying-local-dependency-management-ggo</link>
      <guid>https://dev.to/brunosartori/mastering-npm-link-simplifying-local-dependency-management-ggo</guid>
      <description>&lt;p&gt;&lt;em&gt;by &lt;a href="https://www.linkedin.com/in/bruno-sartori-dev" rel="noopener noreferrer"&gt;Bruno Sartori&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When creating NPM packages, you will eventually need to debug your package by installing it in another NodeJS project to see how your package behaves as a dependency.  Well, you could do this by publishing your NPM package and re-installing it as a dependency in your project every time or copying your package into your project’s &lt;code&gt;node_modules&lt;/code&gt; but… this would be a pain in the ass to say the least 😅. This is where &lt;code&gt;npm link&lt;/code&gt; comes into play.&lt;/p&gt;

&lt;h2&gt;
  
  
  What NPM Link does?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;npm link&lt;/code&gt; is used to create a &lt;a href="https://stackoverflow.com/questions/58314491/what-is-the-purpose-of-creating-a-symbolic-link-between-files" rel="noopener noreferrer"&gt;symlink&lt;/a&gt; between the library &lt;strong&gt;dist&lt;/strong&gt; directory and the application &lt;code&gt;node_modules&lt;/code&gt; directory and add it to the application’s &lt;code&gt;package.json&lt;/code&gt; file as a dependency. This way you can use your local project as a dependency of another project without having to publish it or manually copy it to your &lt;code&gt;node_modules&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup your package for linking
&lt;/h2&gt;

&lt;p&gt;Before linking your package as a dependency using &lt;code&gt;npm link&lt;/code&gt;, be sure you have configured the &lt;code&gt;main&lt;/code&gt; and &lt;code&gt;files&lt;/code&gt; properties in your &lt;code&gt;package.json&lt;/code&gt; file and that you have built your project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt;
    ...
    &lt;span class="s2"&gt;"main"&lt;/span&gt;: &lt;span class="s2"&gt;"dist/index.js"&lt;/span&gt;,
    &lt;span class="s2"&gt;"files"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"dist"&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;/div&gt;



&lt;p&gt;For more information on how to properly create and setup an NPM package, you can read my article &lt;strong&gt;How to create and publish an NPM unscoped and scoped package with Typescript.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Using NPM Link
&lt;/h2&gt;

&lt;p&gt;To link a package with &lt;code&gt;npm link&lt;/code&gt; you simply need to follow these two steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the root directory of the package to be linked by another project (the package that will be used as a dependency by another project) and type &lt;code&gt;npm link&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Go to the root directory of the project that will use your package as a dependency and type &lt;code&gt;npm link [your-package-name]&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that’s it, that’s really all it is. After that you can edit and build your dependency while running your main project and it will automatically update so you can properly debug things. Let’s see this working with an actual example using my package &lt;a href="https://github.com/bruno-sartori/weeb-logger" rel="noopener noreferrer"&gt;&lt;em&gt;Weeb Logger&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real World Example
&lt;/h2&gt;

&lt;p&gt;I’ve created two directories, one with my NPM package called &lt;a href="https://github.com/bruno-sartori/weeb-logger" rel="noopener noreferrer"&gt;weeb-logger&lt;/a&gt; which is a logging tool that displays log information directly in the application so I can see logs in applications without having to open DevTools. This can be usefeul for debbugging and another with a react application created with &lt;code&gt;create-react-app&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxqhy9ptmjqogaz89uawc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxqhy9ptmjqogaz89uawc.png" alt="Projects folder structure" width="244" height="107"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then I go to the weeb-logger project which will be used as a dependency and do &lt;code&gt;npm link&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcfck9spozy6r492jtuuy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcfck9spozy6r492jtuuy.png" alt="npm link on dependency project" width="721" height="108"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And then on test-react-application project I type &lt;code&gt;npm link @bsartori/weeb-logger&lt;/code&gt; which is the name of my package with an organization scope.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs9ku352kmqdikxaxq4cq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs9ku352kmqdikxaxq4cq.png" alt="npm link @bsartori/weeb-logger on main project" width="800" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, in my directory structure we already have &lt;code&gt;@bsartori/weeb-logger&lt;/code&gt; inside the &lt;code&gt;node_modules&lt;/code&gt; folder. Notice that the folder icon indicates that this folder is a symlink. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5jda77qno79zkycc7501.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5jda77qno79zkycc7501.png" alt="Dependency symlink created on main project" width="280" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, in my &lt;code&gt;test-react-application&lt;/code&gt; project, I import my dependency using &lt;code&gt;import logger from '@bsartori/weeb-logger';&lt;/code&gt;. Notice that when hovering your mouse over the dependency name you can see it’s original pathname:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdtpj4tq3ep2ekk780o20.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdtpj4tq3ep2ekk780o20.png" alt="Dependency path highlighted by vscode on mouse over" width="800" height="118"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After importing my dependency, I just do some configuration which the dependency needs and call my logging function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F41wjf4uwo90fry2hyd1l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F41wjf4uwo90fry2hyd1l.png" alt="Using dependency code on main project" width="546" height="261"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, save the file and see the results on your browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpi2dax3m5fapdoog77c3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpi2dax3m5fapdoog77c3.png" alt="Final result" width="546" height="261"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In conclusion, &lt;code&gt;npm link&lt;/code&gt; is a powerful and convenient tool for local development of NPM packages. It allows you to streamline the testing and debugging process without the need for constantly publishing or copying your package into the project’s &lt;code&gt;node_modules&lt;/code&gt;. By creating a symlink, you can easily update and test your package in real-time, making development more efficient. Whether you're working on small utilities or larger libraries, incorporating &lt;code&gt;npm link&lt;/code&gt; into your workflow can save time and effort, allowing for smoother integration between projects.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check Out My Other Articles
&lt;/h3&gt;

&lt;p&gt;If you liked this guide, you might enjoy some of my other posts where I share more tips and tricks for devs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://medium.com/@brunosartori.dev/using-husky-to-help-you-avoid-f-ing-up-semantic-versioning-8098eb3d74d1" rel="noopener noreferrer"&gt;&lt;strong&gt;Using Husky to Help You Avoid F&lt;/strong&gt;&lt;strong&gt;ing Up Semantic Versioning&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;
A look at how Husky can save you from versioning headaches and keep your workflow smooth.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://medium.com/@brunosartori.dev/a-practical-guide-to-semantic-versioning-how-and-when-to-update-your-versions-406708ceef3d" rel="noopener noreferrer"&gt;&lt;strong&gt;A Practical Guide to Semantic Versioning: How and When to Update Your Versions&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;
Quick tips on when to bump your versions and how to avoid common mistakes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://medium.com/@brunosartori.dev/how-to-highlight-your-github-repositories-on-linkedin-2d3a120e9592" rel="noopener noreferrer"&gt;&lt;strong&gt;How to Highlight Your GitHub Repositories on LinkedIn&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;
A simple guide to show off your GitHub work on LinkedIn.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>npm</category>
      <category>node</category>
      <category>softwaredevelopment</category>
      <category>npmlink</category>
    </item>
    <item>
      <title>Using Husky to help you avoid f****ing up Semantic Versioning</title>
      <dc:creator>Bruno Sartori</dc:creator>
      <pubDate>Sun, 08 Sep 2024 20:47:57 +0000</pubDate>
      <link>https://dev.to/brunosartori/using-husky-to-help-you-avoid-fing-up-semantic-versioning-1cjh</link>
      <guid>https://dev.to/brunosartori/using-husky-to-help-you-avoid-fing-up-semantic-versioning-1cjh</guid>
      <description>&lt;p&gt;by &lt;a href="https://www.linkedin.com/in/bruno-sartori-dev" rel="noopener noreferrer"&gt;Bruno Sartori&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;The use of &lt;a href="https://dev.to/brunosartori/a-practical-guide-to-semantic-versioning-how-and-when-to-update-your-versions-2c19"&gt;Semantic Versioning&lt;/a&gt; is very important to keep your users informed about changes that may impact how they interact with the software, maintain compatibility between libraries, facilitate collaboration among teams by reducing conflicts and communication failures regarding the current state of the software, among many other things.&lt;/p&gt;

&lt;p&gt;That said, keeping semantic versioning flawless can be quite a challenge, either because not everyone who contributes to the code practices it correctly — such as incorrectly changing the MAJOR, MINOR, and PATCH components — or because we may simply forget to update the version before committing or pushing the code to the repository. In any case, manual processes are always prone to human error, so it would be interesting if we could create an automated way to validate whether a version bump is necessary to prevent potential issues. &lt;/p&gt;

&lt;p&gt;Fortunately, Git has hooks, which are scripts that Git automatically runs before or after certain events like commit or push. We can leverage them to alert us to possible changes that break code compatibility, keeping semantic versioning neat and tidy &lt;strong&gt;😊&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is Husky?
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/typicode/husky" rel="noopener noreferrer"&gt;Husky&lt;/a&gt; is an NPM package that makes it easy to integrate Git Hooks into your project. It can be used to automate tasks such as running tests, linters, etc. It is extremely fast and weighs only 2kb. Additionally, with Husky, we can create hooks using &lt;strong&gt;POSIX shell scripts&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  How to install Husky
&lt;/h1&gt;

&lt;p&gt;Use your favorite package manager to install the dependency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add --dev husky
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use &lt;a href="https://github.com/npm/npx" rel="noopener noreferrer"&gt;NPX&lt;/a&gt; to automatically setup husky for you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx husky init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a &lt;code&gt;pre-commit&lt;/code&gt; script in &lt;code&gt;.husky/&lt;/code&gt; folder and updates &lt;code&gt;prepare&lt;/code&gt; script in your &lt;code&gt;package.json&lt;/code&gt; file. Boom! its all good to go.&lt;/p&gt;

&lt;h1&gt;
  
  
  Creating a pre-commit hook to validate possible breaking changes in the code and prevent us from pushing them without incrementing MAJOR version.
&lt;/h1&gt;

&lt;p&gt;On &lt;code&gt;.husky/&lt;/code&gt; folder, open the &lt;code&gt;pre-commit&lt;/code&gt; file that Husky has already created for you and paste the following code. Don’t worry, we will talk about what it’s doing in a second.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;yellow&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'\\033[0;33m'&lt;/span&gt;
&lt;span class="nv"&gt;green&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'\\033[0;32m'&lt;/span&gt;
&lt;span class="nv"&gt;blue&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'\\033[0;34m'&lt;/span&gt;
&lt;span class="nv"&gt;red&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'\\033[0;31m'&lt;/span&gt;
&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'\\033[0m'&lt;/span&gt;

&lt;span class="nv"&gt;ABORT_IF_ANY_VERSION_WAS_NOT_UPDATED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0
&lt;span class="nv"&gt;ABORT_IF_MAJOR_VERSION_WAS_NOT_UPDATED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1

&lt;span class="nv"&gt;POTENTIALLY_BREAKABLE_CHANGES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0

&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; nounset

compare_strings&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;old_string&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="nv"&gt;new_string&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

  &lt;span class="c"&gt;# Initialize the resulting string&lt;/span&gt;
  &lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;

  &lt;span class="c"&gt;# Initialize the indexes&lt;/span&gt;
  &lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0
  &lt;span class="nv"&gt;j&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0

  &lt;span class="c"&gt;# Traverse the new string and compare it with the old string&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="nt"&gt;-lt&lt;/span&gt; &lt;span class="k"&gt;${#&lt;/span&gt;&lt;span class="nv"&gt;new_string&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nv"&gt;new_char&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;new_string&lt;/span&gt;:i:1&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="nv"&gt;old_char&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;old_string&lt;/span&gt;:j:1&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

    &lt;span class="c"&gt;# If the character from the new string is equal to the old one, add it without highlight&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$new_char&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$old_char&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
      &lt;/span&gt;&lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$result$new_char&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
      &lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;i+1&lt;span class="k"&gt;))&lt;/span&gt;
      &lt;span class="nv"&gt;j&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;j+1&lt;span class="k"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="c"&gt;# If the character from the new string is not in the old string, highlight it in green&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$new_char&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$old_char&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$new_char&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$old_char&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;green&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;new_char&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;i+1&lt;span class="k"&gt;))&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="c"&gt;# Add characters from the old string until finding the matching character&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$new_char&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$old_char&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$j&lt;/span&gt; &lt;span class="nt"&gt;-lt&lt;/span&gt; &lt;span class="k"&gt;${#&lt;/span&gt;&lt;span class="nv"&gt;old_string&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
          &lt;/span&gt;&lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;red&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;old_char&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
          &lt;span class="nv"&gt;j&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;j+1&lt;span class="k"&gt;))&lt;/span&gt;
          &lt;span class="nv"&gt;old_char&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;old_string&lt;/span&gt;:j:1&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="k"&gt;done
      fi
    fi
  done&lt;/span&gt;

  &lt;span class="c"&gt;# Add the remaining characters from the old string, if any&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$j&lt;/span&gt; &lt;span class="nt"&gt;-lt&lt;/span&gt; &lt;span class="k"&gt;${#&lt;/span&gt;&lt;span class="nv"&gt;old_string&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;red&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;old_string&lt;/span&gt;:j:1&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="nv"&gt;j&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;j+1&lt;span class="k"&gt;))&lt;/span&gt;
  &lt;span class="k"&gt;done&lt;/span&gt;

  &lt;span class="c"&gt;# Return the result&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;blue&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;Initializing Husky&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;n"&lt;/span&gt;

&lt;span class="nv"&gt;REPO_ROOT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git rev-parse &lt;span class="nt"&gt;--show-toplevel&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nv"&gt;SITE_CHANGES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git status &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REPO_ROOT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"Detected &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;yellow&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="nv"&gt;$SITE_CHANGES&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; changes&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;n"&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SITE_CHANGES&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;

  &lt;span class="c"&gt;# Check files for function signature changes&lt;/span&gt;
  &lt;span class="nv"&gt;CHANGED_FILES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git diff &lt;span class="nt"&gt;--cached&lt;/span&gt; &lt;span class="nt"&gt;--name-only&lt;/span&gt; &lt;span class="nt"&gt;--diff-filter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ACM | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s1"&gt;'\\.(ts|tsx|js|jsx)$'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CHANGED_FILES&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;blue&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;Checking TypeScript files for potentially breakable changes...&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;n"&lt;/span&gt;

    &lt;span class="c"&gt;# Define the regex pattern and dont ask me how I get this right (hint: ends with "gpt")&lt;/span&gt;
    &lt;span class="nv"&gt;REGEX&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"function&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s+[a-zA-Z_&lt;/span&gt;&lt;span class="nv"&gt;$]&lt;/span&gt;&lt;span class="s2"&gt;[0-9a-zA-Z_&lt;/span&gt;&lt;span class="nv"&gt;$]&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s*&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;([^)]*&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;)(?:&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s*:&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s*[a-zA-Z_&lt;/span&gt;&lt;span class="nv"&gt;$]&lt;/span&gt;&lt;span class="s2"&gt;[0-9a-zA-Z_&lt;/span&gt;&lt;span class="nv"&gt;$]&lt;/span&gt;&lt;span class="s2"&gt;*)?&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s*(?:;|&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;{)|[a-zA-Z_&lt;/span&gt;&lt;span class="nv"&gt;$]&lt;/span&gt;&lt;span class="s2"&gt;[0-9a-zA-Z_&lt;/span&gt;&lt;span class="nv"&gt;$]&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s*=&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s*&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;([^)]*&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;)(?:&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s*:&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s*[a-zA-Z_&lt;/span&gt;&lt;span class="nv"&gt;$]&lt;/span&gt;&lt;span class="s2"&gt;[0-9a-zA-Z_&lt;/span&gt;&lt;span class="nv"&gt;$]&lt;/span&gt;&lt;span class="s2"&gt;*)?&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s*=&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s*[^&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;{]*?(?:;|&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s*)|(?:public|private|protected)?&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s*[a-zA-Z_&lt;/span&gt;&lt;span class="nv"&gt;$]&lt;/span&gt;&lt;span class="s2"&gt;[0-9a-zA-Z_&lt;/span&gt;&lt;span class="nv"&gt;$]&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s*&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;([^)]*&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;)(?:&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s*:&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s*[a-zA-Z_&lt;/span&gt;&lt;span class="nv"&gt;$]&lt;/span&gt;&lt;span class="s2"&gt;[0-9a-zA-Z_&lt;/span&gt;&lt;span class="nv"&gt;$]&lt;/span&gt;&lt;span class="s2"&gt;*)?&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s*(?:;|&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;{)"&lt;/span&gt;

    &lt;span class="c"&gt;# Iterate over staged TypeScript files&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;FILE &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;$CHANGED_FILES&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
      if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REPO_ROOT&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;$FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"Checking file &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;yellow&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="nv"&gt;$FILE&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;...&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;n"&lt;/span&gt;

        &lt;span class="c"&gt;# Get added and removed changes&lt;/span&gt;
        &lt;span class="nv"&gt;STAGED_ADDITIONS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git diff &lt;span class="nt"&gt;--cached&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REPO_ROOT&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;$FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"^&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;+[^+]"&lt;/span&gt; | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/^\\+//'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
        &lt;span class="nv"&gt;STAGED_REMOVALS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git diff &lt;span class="nt"&gt;--cached&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REPO_ROOT&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;$FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"^&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;-[^-]"&lt;/span&gt; | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/^\\-//'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

        &lt;span class="nv"&gt;ADDITIONS_MATCHED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;
        &lt;span class="nv"&gt;REMOVALS_MATCHED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;

        &lt;span class="c"&gt;# Check if STAGED_ADDITIONS is not empty and execute grep if not&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$STAGED_ADDITIONS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
          &lt;span class="c"&gt;# Capture the part that matches the regex&lt;/span&gt;
          &lt;span class="nv"&gt;ADDITIONS_MATCHED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"%s"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$STAGED_ADDITIONS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-P&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGEX&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;fi&lt;/span&gt;

        &lt;span class="c"&gt;# Check if STAGED_REMOVALS is not empty and execute grep if not&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$STAGED_REMOVALS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
          &lt;span class="c"&gt;# Capture the part that matches the regex&lt;/span&gt;
          &lt;span class="nv"&gt;REMOVALS_MATCHED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"%s"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$STAGED_REMOVALS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-P&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGEX&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;fi

        if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ADDITIONS_MATCHED&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
          &lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;red&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;Signature changes detected in &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;yellow&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="nv"&gt;$FILE&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;. Showing changes:&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;n"&lt;/span&gt;
          &lt;span class="c"&gt;# Call the function and display the result&lt;/span&gt;
          compare_strings &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REMOVALS_MATCHED&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ADDITIONS_MATCHED&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
          &lt;span class="nv"&gt;POTENTIALLY_BREAKABLE_CHANGES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
        &lt;span class="k"&gt;fi
      fi
    done

    if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$POTENTIALLY_BREAKABLE_CHANGES&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-eq&lt;/span&gt; 1 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
      &lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"Checking to make sure package version was updated...&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;n"&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ABORT_IF_ANY_VERSION_WAS_NOT_UPDATED&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-eq&lt;/span&gt; 1 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nv"&gt;VERSION_CHANGED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git diff &lt;span class="nt"&gt;-G&lt;/span&gt; &lt;span class="s1"&gt;'"version":'&lt;/span&gt; &lt;span class="nt"&gt;--cached&lt;/span&gt; package.json | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VERSION_CHANGED&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; &lt;span class="s2"&gt;"0"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
          &lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;green&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;Version was updated!  Continuing...&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;n"&lt;/span&gt;
        &lt;span class="k"&gt;else
          &lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;red&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;Version was not updated :( Aborting commit.&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;n"&lt;/span&gt;
          &lt;span class="nb"&gt;exit &lt;/span&gt;1
        &lt;span class="k"&gt;fi
      elif&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ABORT_IF_MAJOR_VERSION_WAS_NOT_UPDATED&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-eq&lt;/span&gt; 1 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nv"&gt;CURRENT_VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-oP&lt;/span&gt; &lt;span class="s1"&gt;'"version":\\s*"\\K[0-9]+\\.[0-9]+\\.[0-9]+"'&lt;/span&gt; package.json | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'"'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
        &lt;span class="nv"&gt;CURRENT_MAJOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CURRENT_VERSION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="s1"&gt;'.'&lt;/span&gt; &lt;span class="nt"&gt;-f1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

        &lt;span class="nv"&gt;STAGED_VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git diff &lt;span class="nt"&gt;--cached&lt;/span&gt; package.json | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-oP&lt;/span&gt; &lt;span class="s1"&gt;'"version":\\s*"\\K[0-9]+\\.[0-9]+\\.[0-9]+"'&lt;/span&gt; | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'"'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
        &lt;span class="nv"&gt;STAGED_MAJOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$STAGED_VERSION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="s1"&gt;'.'&lt;/span&gt; &lt;span class="nt"&gt;-f1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$STAGED_MAJOR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
          &lt;span class="c"&gt;# Check if the MAJOR version has changed&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CURRENT_MAJOR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$STAGED_MAJOR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
            &lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;green&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;MAJOR version was updated! Continuing...&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;n"&lt;/span&gt;
          &lt;span class="k"&gt;else
            &lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;red&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;MAJOR version was not updated :( Aborting commit.&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;n"&lt;/span&gt;
          &lt;span class="k"&gt;fi
        else 
          &lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;red&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;MAJOR version was not updated :( Aborting commit.&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;n"&lt;/span&gt;
          &lt;span class="nb"&gt;exit &lt;/span&gt;1
        &lt;span class="k"&gt;fi
      fi
    fi
  fi
fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let’s dive into this code for a minute and see what it is doing.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Script Initialization
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;yellow&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'\\033[0;33m'&lt;/span&gt;
&lt;span class="nv"&gt;green&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'\\033[0;32m'&lt;/span&gt;
&lt;span class="nv"&gt;blue&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'\\033[0;34m'&lt;/span&gt;
&lt;span class="nv"&gt;red&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'\\033[0;31m'&lt;/span&gt;
&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'\\033[0m'&lt;/span&gt;

&lt;span class="nv"&gt;ABORT_IF_ANY_VERSION_WAS_NOT_UPDATED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0
&lt;span class="nv"&gt;ABORT_IF_MAJOR_VERSION_WAS_NOT_UPDATED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1

&lt;span class="nv"&gt;POTENTIALLY_BREAKABLE_CHANGES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0

&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; nounset
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  First, we create some variables for changing the color of the output.&lt;/li&gt;
&lt;li&gt;  The two flags &lt;code&gt;ABORT_IF_ANY_VERSION_WAS_NOT_UPDATED&lt;/code&gt; and &lt;code&gt;ABORT_IF_MAJOR_VERSION_WAS_NOT_UPDATED&lt;/code&gt; let’s you have some control of when to abort the push process.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;POTENTIALLY_BREAKABLE_CHANGES&lt;/code&gt; is a flag to identify if the script has found a breakable change in potential.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;set -o nounset&lt;/code&gt;: This enables a mode where using undeclared variables will trigger an error. It helps avoid accidental errors by ensuring that all variables are defined before being used.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. compare_strings Function
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;compare_strings&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;old_string&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="nv"&gt;new_string&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

  &lt;span class="c"&gt;# Initialize the resulting string&lt;/span&gt;
  &lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;

  &lt;span class="c"&gt;# Initialize the indexes&lt;/span&gt;
  &lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0
  &lt;span class="nv"&gt;j&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0

  &lt;span class="c"&gt;# Traverse the new string and compare it with the old string&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="nt"&gt;-lt&lt;/span&gt; &lt;span class="k"&gt;${#&lt;/span&gt;&lt;span class="nv"&gt;new_string&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nv"&gt;new_char&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;new_string&lt;/span&gt;:i:1&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="nv"&gt;old_char&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;old_string&lt;/span&gt;:j:1&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  The &lt;code&gt;compare_strings&lt;/code&gt; function will be used to print what was changed in function's signatures of the staged files.&lt;/li&gt;
&lt;li&gt;  The &lt;code&gt;while&lt;/code&gt; loop iterates through each character of the &lt;code&gt;new_string&lt;/code&gt; and compares it to the corresponding character in the &lt;code&gt;old_string&lt;/code&gt;. &lt;code&gt;new_char&lt;/code&gt; and &lt;code&gt;old_char&lt;/code&gt; hold the current characters from each string, based on their indexes.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$new_char&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$old_char&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$result$new_char&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;i+1&lt;span class="k"&gt;))&lt;/span&gt;
  &lt;span class="nv"&gt;j&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;j+1&lt;span class="k"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;else
  if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$new_char&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$old_char&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$new_char&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$old_char&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;green&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;new_char&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;i+1&lt;span class="k"&gt;))&lt;/span&gt;
  &lt;span class="k"&gt;else
    while&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$new_char&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$old_char&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$j&lt;/span&gt; &lt;span class="nt"&gt;-lt&lt;/span&gt; &lt;span class="k"&gt;${#&lt;/span&gt;&lt;span class="nv"&gt;old_string&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
      &lt;/span&gt;&lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;red&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;old_char&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
      &lt;span class="nv"&gt;j&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;j+1&lt;span class="k"&gt;))&lt;/span&gt;
      &lt;span class="nv"&gt;old_char&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;old_string&lt;/span&gt;:j:1&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;done
  fi
fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  If the current characters from both strings match, the character from the &lt;code&gt;new_string&lt;/code&gt; is appended to the &lt;code&gt;result&lt;/code&gt; without any highlighting.&lt;/li&gt;
&lt;li&gt;  The indexes &lt;code&gt;i&lt;/code&gt; and &lt;code&gt;j&lt;/code&gt; are incremented to move to the next character in both strings.&lt;/li&gt;
&lt;li&gt;  If the current character from the &lt;code&gt;new_string&lt;/code&gt; differs from the &lt;code&gt;old_string&lt;/code&gt;, the character from &lt;code&gt;new_string&lt;/code&gt; is highlighted in green (using &lt;code&gt;green&lt;/code&gt; and &lt;code&gt;no_color&lt;/code&gt;) and added to the &lt;code&gt;result&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  The index &lt;code&gt;i&lt;/code&gt; is incremented to move to the next character of the &lt;code&gt;new_string&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  If the characters don’t match and the &lt;code&gt;new_char&lt;/code&gt; is not present in the &lt;code&gt;old_string&lt;/code&gt;, the function iterates through the &lt;code&gt;old_string&lt;/code&gt; until a match is found, highlighting the unmatched characters in red (indicating they have been removed).&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;j&lt;/code&gt; is incremented while traversing the &lt;code&gt;old_string&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$j&lt;/span&gt; &lt;span class="nt"&gt;-lt&lt;/span&gt; &lt;span class="k"&gt;${#&lt;/span&gt;&lt;span class="nv"&gt;old_string&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;red&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;old_string&lt;/span&gt;:j:1&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="nv"&gt;j&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;j+1&lt;span class="k"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;done

&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  After comparing all characters in the &lt;code&gt;new_string&lt;/code&gt;, if there are remaining characters in the &lt;code&gt;old_string&lt;/code&gt;, they are appended to the &lt;code&gt;result&lt;/code&gt; highlighted in red to indicate they were removed.&lt;/li&gt;
&lt;li&gt;  Finally, the function prints the &lt;code&gt;result&lt;/code&gt;, which contains the compared strings with characters highlighted to indicate additions (green) or removals (red).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Finding updates in function’s signature
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;blue&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;Initializing Husky&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;n"&lt;/span&gt;

&lt;span class="nv"&gt;REPO_ROOT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git rev-parse &lt;span class="nt"&gt;--show-toplevel&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;SITE_CHANGES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git status &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REPO_ROOT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"Detected &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;yellow&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="nv"&gt;$SITE_CHANGES&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; changes&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;n"&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SITE_CHANGES&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;

  &lt;span class="c"&gt;# Check files for function signature changes&lt;/span&gt;
  &lt;span class="nv"&gt;CHANGED_FILES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git diff &lt;span class="nt"&gt;--cached&lt;/span&gt; &lt;span class="nt"&gt;--name-only&lt;/span&gt; &lt;span class="nt"&gt;--diff-filter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ACM | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s1"&gt;'\\\\.(ts|tsx|js|jsx)$'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CHANGED_FILES&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;blue&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;Checking TypeScript files for potentially breakable changes...&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;n"&lt;/span&gt;

    &lt;span class="c"&gt;# Define the regex pattern and dont ask me how I get this right (hint: ends with "gpt")&lt;/span&gt;
    &lt;span class="nv"&gt;REGEX&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"function&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;s+[a-zA-Z_&lt;/span&gt;&lt;span class="nv"&gt;$]&lt;/span&gt;&lt;span class="s2"&gt;[0-9a-zA-Z_&lt;/span&gt;&lt;span class="nv"&gt;$]&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;s*&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;([^)]*&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;)(?:&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;s*:&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;s*[a-zA-Z_&lt;/span&gt;&lt;span class="nv"&gt;$]&lt;/span&gt;&lt;span class="s2"&gt;[0-9a-zA-Z_&lt;/span&gt;&lt;span class="nv"&gt;$]&lt;/span&gt;&lt;span class="s2"&gt;*)?&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;s*(?:;|&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;{)|[a-zA-Z_&lt;/span&gt;&lt;span class="nv"&gt;$]&lt;/span&gt;&lt;span class="s2"&gt;[0-9a-zA-Z_&lt;/span&gt;&lt;span class="nv"&gt;$]&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;s*=&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;s*&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;([^)]*&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;)(?:&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;s*:&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;s*[a-zA-Z_&lt;/span&gt;&lt;span class="nv"&gt;$]&lt;/span&gt;&lt;span class="s2"&gt;[0-9a-zA-Z_&lt;/span&gt;&lt;span class="nv"&gt;$]&lt;/span&gt;&lt;span class="s2"&gt;*)?&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;s*=&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;s*[^&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;{]*?(?:;|&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;s*)|(?:public|private|protected)?&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;s*[a-zA-Z_&lt;/span&gt;&lt;span class="nv"&gt;$]&lt;/span&gt;&lt;span class="s2"&gt;[0-9a-zA-Z_&lt;/span&gt;&lt;span class="nv"&gt;$]&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;s*&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;([^)]*&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;)(?:&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;s*:&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;s*[a-zA-Z_&lt;/span&gt;&lt;span class="nv"&gt;$]&lt;/span&gt;&lt;span class="s2"&gt;[0-9a-zA-Z_&lt;/span&gt;&lt;span class="nv"&gt;$]&lt;/span&gt;&lt;span class="s2"&gt;*)?&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;s*(?:;|&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;{)"&lt;/span&gt;

    &lt;span class="k"&gt;for &lt;/span&gt;FILE &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;$CHANGED_FILES&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
      if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REPO_ROOT&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;$FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"Checking file &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;yellow&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="nv"&gt;$FILE&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;...&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;n"&lt;/span&gt;

        &lt;span class="nv"&gt;STAGED_ADDITIONS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git diff &lt;span class="nt"&gt;--cached&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REPO_ROOT&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;$FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"^&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;+[^+]"&lt;/span&gt; | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/^\\\\+//'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
        &lt;span class="nv"&gt;STAGED_REMOVALS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git diff &lt;span class="nt"&gt;--cached&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REPO_ROOT&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;$FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"^&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;-[^-]"&lt;/span&gt; | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/^\\\\-//'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ADDITIONS_MATCHED&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
          &lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;red&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;Signature changes detected in &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;yellow&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="nv"&gt;$FILE&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;. Showing changes:&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;n"&lt;/span&gt;
          compare_strings &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REMOVALS_MATCHED&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ADDITIONS_MATCHED&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
          &lt;span class="nv"&gt;POTENTIALLY_BREAKABLE_CHANGES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
        &lt;span class="k"&gt;fi
      fi
    done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;REPO_ROOT&lt;/code&gt; is set to the root directory of the git repository using &lt;code&gt;git rev-parse --show-toplevel&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;SITE_CHANGES&lt;/code&gt; counts the number of changes detected in the repository using &lt;code&gt;git status&lt;/code&gt; and &lt;code&gt;wc -l&lt;/code&gt; (to count the lines in the output).&lt;/li&gt;
&lt;li&gt;  If changes are detected in the repository, the script looks for staged files that match the extensions &lt;code&gt;.ts&lt;/code&gt;, &lt;code&gt;.tsx&lt;/code&gt;, &lt;code&gt;.js&lt;/code&gt;, or &lt;code&gt;.jsx&lt;/code&gt; using &lt;code&gt;git diff --cached&lt;/code&gt;. These files are stored in &lt;code&gt;CHANGED_FILES&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  If there are changed files, the script informs the user and defines a &lt;code&gt;REGEX&lt;/code&gt; pattern to identify function signatures, arrow functions, and class methods in TypeScript or JavaScript files.&lt;/li&gt;
&lt;li&gt;  The script then iterates over each file in &lt;code&gt;CHANGED_FILES&lt;/code&gt;, checking if it exists in the repository root.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;STAGED_ADDITIONS&lt;/code&gt; and &lt;code&gt;STAGED_REMOVALS&lt;/code&gt; capture the added and removed lines from the staged files by filtering lines starting with &lt;code&gt;+&lt;/code&gt; or &lt;code&gt;-&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  If there are any function signature changes detected, the &lt;code&gt;compare_strings&lt;/code&gt; function is called to highlight the differences between the added and removed function signatures and sets the flag &lt;code&gt;POTENTIALLY_BREAKABLE_CHANGES&lt;/code&gt; to 1 (true).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Check for Version Updates
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$POTENTIALLY_BREAKABLE_CHANGES&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-eq&lt;/span&gt; 1 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"Checking to make sure package version was updated...&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;n"&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ABORT_IF_ANY_VERSION_WAS_NOT_UPDATED&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-eq&lt;/span&gt; 1 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nv"&gt;VERSION_CHANGED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git diff &lt;span class="nt"&gt;-G&lt;/span&gt; &lt;span class="s1"&gt;'"version":'&lt;/span&gt; &lt;span class="nt"&gt;--cached&lt;/span&gt; package.json | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VERSION_CHANGED&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; &lt;span class="s2"&gt;"0"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
      &lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;green&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;Version was updated!  Continuing...&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;n"&lt;/span&gt;
    &lt;span class="k"&gt;else
      &lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;red&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;Version was not updated :( Aborting commit.&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;n"&lt;/span&gt;
      &lt;span class="nb"&gt;exit &lt;/span&gt;1
    &lt;span class="k"&gt;fi
  elif&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ABORT_IF_MAJOR_VERSION_WAS_NOT_UPDATED&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-eq&lt;/span&gt; 1 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nv"&gt;CURRENT_VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-oP&lt;/span&gt; &lt;span class="s1"&gt;'"version":\\s*"\\K[0-9]+\\.[0-9]+\\.[0-9]+"'&lt;/span&gt; package.json | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'"'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;CURRENT_MAJOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CURRENT_VERSION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="s1"&gt;'.'&lt;/span&gt; &lt;span class="nt"&gt;-f1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="nv"&gt;STAGED_VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git diff &lt;span class="nt"&gt;--cached&lt;/span&gt; package.json | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-oP&lt;/span&gt; &lt;span class="s1"&gt;'"version":\\s*"\\K[0-9]+\\.[0-9]+\\.[0-9]+"'&lt;/span&gt; | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'"'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;STAGED_MAJOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$STAGED_VERSION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="s1"&gt;'.'&lt;/span&gt; &lt;span class="nt"&gt;-f1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$STAGED_MAJOR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
      &lt;span class="c"&gt;# Check if the MAJOR version has changed&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CURRENT_MAJOR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$STAGED_MAJOR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;green&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;MAJOR version was updated! Continuing...&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;n"&lt;/span&gt;
      &lt;span class="k"&gt;else
        &lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;red&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;MAJOR version was not updated :( Aborting commit.&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;n"&lt;/span&gt;
      &lt;span class="k"&gt;fi
    else 
      &lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;red&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;MAJOR version was not updated :( Aborting commit.&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;no_color&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;n"&lt;/span&gt;
      &lt;span class="nb"&gt;exit &lt;/span&gt;1
    &lt;span class="k"&gt;fi
  fi
fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  If potencial breakable changes are detected, the script checks for the two flags for defining when to abort the process. if &lt;code&gt;ABORT_IF_ANY_VERSION_WAS_NOT_UPDATED&lt;/code&gt; is set to true, it checks whether the &lt;code&gt;package.json&lt;/code&gt; version was updated. If not, the commit is aborted with a message.&lt;/li&gt;
&lt;li&gt;  if &lt;code&gt;ABORT_IF_MAJOR_VERSION_WAS_NOT_UPDATED&lt;/code&gt; is set to true, it extracts the &lt;code&gt;CURRENT_VERSION&lt;/code&gt; of the &lt;code&gt;package.json&lt;/code&gt; file using &lt;code&gt;grep&lt;/code&gt;. The regular expression captures the version (e.g., &lt;code&gt;1.2.3&lt;/code&gt;), and &lt;code&gt;tr -d '"'&lt;/code&gt; removes the surrounding double quotes.&lt;/li&gt;
&lt;li&gt;  Then it extracts the &lt;code&gt;CURRENT_MAJOR&lt;/code&gt; version part (e.g., &lt;code&gt;1&lt;/code&gt; from &lt;code&gt;1.2.3&lt;/code&gt;) using &lt;code&gt;cut -d'.' -f1&lt;/code&gt;, which splits the version by dots and selects the first part.&lt;/li&gt;
&lt;li&gt;  It does the same thing for the &lt;code&gt;STAGED_VERSION&lt;/code&gt; and &lt;code&gt;STAGED_MAJOR&lt;/code&gt; but using &lt;code&gt;git diff --cached&lt;/code&gt; to capture the differences in &lt;code&gt;package.json&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;  Finally, it compares the &lt;strong&gt;current and staged major versions&lt;/strong&gt;. If they are different, it means the &lt;strong&gt;MAJOR version&lt;/strong&gt; was updated correctly, and the script prints a success message and continues. If the major versions are the same, it prints an error message and aborts the commit process with &lt;code&gt;exit 1&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Using our Hook
&lt;/h1&gt;

&lt;p&gt;To verify the hook running, change some random function’s signature like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvm5mg5ijv1vf8c8s6c4k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvm5mg5ijv1vf8c8s6c4k.png" alt="Updating function signature 1" width="800" height="153"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa3ke773llcfvvqs6a9yo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa3ke773llcfvvqs6a9yo.png" alt="Updating function signature 2" width="800" height="121"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsyx7zyxdrc0zaq3g6gkb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsyx7zyxdrc0zaq3g6gkb.png" alt="Updating function signature 3" width="800" height="157"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhxiy9hm3mlqojl49j5vi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhxiy9hm3mlqojl49j5vi.png" alt="Updating function signature 44" width="800" height="157"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, run the command &lt;code&gt;git add --all&lt;/code&gt; and commit try to commit them using &lt;code&gt;git commit -m 'my hook test'&lt;/code&gt;, the hook will execute and you will see the following message:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv8uu3xuz378kyydfhfp0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv8uu3xuz378kyydfhfp0.png" alt="Hook aborting commit" width="666" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that’s it! the commit process will be aborted and you will not be able to commit changes until you increment the MAJOR version in your &lt;code&gt;package.json&lt;/code&gt; file. If you do that, the hook will allow you to commit like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fldy3fr4jw4xnvhmk7sdg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fldy3fr4jw4xnvhmk7sdg.png" alt="Hook allowing commit" width="666" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Improving the script
&lt;/h1&gt;

&lt;p&gt;As much as this script can help you manage semantic versioning, it is still very rudimentary, and there is room for several improvements. Some possible enhancements include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Better analyzing the tested function to understand if it directly interacts with the end user of the code, increasing the certainty that changing its signature constitutes a breakable change.&lt;/li&gt;
&lt;li&gt;  Looking for changes in API route addresses.&lt;/li&gt;
&lt;li&gt;  Searching for changes in the contract of input and output types.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you liked this script and would like to help improve it, feel free to make modifications. And, if you’d like, send me your changes so I can also benefit from your improvements 😂&lt;/p&gt;

&lt;p&gt;For now, this script is hosted in a &lt;a href="https://gist.github.com/bruno-sartori/91666eb457dacc5ec8072055c1fe4174#file-pre-push-sh" rel="noopener noreferrer"&gt;Gist&lt;/a&gt;, but I could create a repository where you can submit a PR, allowing us to track contributions from collaborators.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Integrating Husky with Git hooks allows us to automate the process of checking for potentially breaking changes in code and enforcing semantic versioning best practices. By utilizing scripts like the one demonstrated, we can identify updates in function signatures and ensure that the MAJOR version is incremented when necessary, reducing the risk of introducing breaking changes without proper versioning. This approach helps maintain a clean, organized versioning system while minimizing human error, allowing teams to collaborate more effectively and safely push code changes without compromising software stability.&lt;/p&gt;

&lt;h1&gt;
  
  
  Further Reading
&lt;/h1&gt;

&lt;p&gt;Don’t forget to check out my article on &lt;a href="https://dev.to/brunosartori/a-practical-guide-to-semantic-versioning-how-and-when-to-update-your-versions-2c19"&gt;Semantic Versioning&lt;/a&gt;. And if you’re curious about how to showcase your GitHub repositories on LinkedIn, &lt;a href="https://dev.to/brunosartori/how-to-highlight-your-github-repositories-on-linkedin-pg1"&gt;this one’s for you&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;If you enjoyed this article, please leave that naughty like and if you got questions drop them in the comments &lt;strong&gt;🙌&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>semanticversioning</category>
      <category>husky</category>
      <category>githooks</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>A Practical Guide to Semantic Versioning: How and When to Update Your Versions</title>
      <dc:creator>Bruno Sartori</dc:creator>
      <pubDate>Fri, 30 Aug 2024 21:39:54 +0000</pubDate>
      <link>https://dev.to/brunosartori/a-practical-guide-to-semantic-versioning-how-and-when-to-update-your-versions-2c19</link>
      <guid>https://dev.to/brunosartori/a-practical-guide-to-semantic-versioning-how-and-when-to-update-your-versions-2c19</guid>
      <description>&lt;p&gt;&lt;a href="https://media.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%2F6tslml7cfvyx9azi739i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F6tslml7cfvyx9azi739i.png" alt="Semantic Versioning Meme"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;by &lt;a href="https://www.linkedin.com/in/bruno-sartori-dev" rel="noopener noreferrer"&gt;Bruno Sartori&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Semantic versioning is a convention for naming software versions in a way that clarifies what updates kinds of updates is made in an application or library. The main idea is to use a sequence of three numbers where each number has its specific meaning.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fzcfv3s4nfr1jdm0thp1c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fzcfv3s4nfr1jdm0thp1c.png" alt="Visual description of Semantic Versioning components"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How does it work?
&lt;/h2&gt;

&lt;p&gt;Semantic versioning is based on three core components: &lt;strong&gt;MAJOR&lt;/strong&gt;, &lt;strong&gt;MINOR&lt;/strong&gt;, and &lt;strong&gt;PATCH&lt;/strong&gt;. Each of these components plays a specific role in indicating the nature of changes in a new release. Here's a breakdown of how each part works:&lt;/p&gt;

&lt;h3&gt;
  
  
  MAJOR (X.0.0):
&lt;/h3&gt;

&lt;p&gt;This is only incremented when there are changes that are incompatible with previous versions. Many times, updates in the code can affect the contract, making obligatory for users to update the way they use your new version. In this cases you need to specify that the major version was updated.&lt;/p&gt;

&lt;h3&gt;
  
  
  MINOR (0.X.0):
&lt;/h3&gt;

&lt;p&gt;This one is incremented when there are new features which are compatible with previous versions. Additions like new methods or configuration options enter on this category.  &lt;/p&gt;

&lt;h3&gt;
  
  
  PATCH (0.0.X):
&lt;/h3&gt;

&lt;p&gt;This is incremented only when there are retro compatible bugfixes. These changes don't add new features but improve stability and performance of the software.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Examples
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1.0.0 to 2.0.0:&lt;/strong&gt; Breakable changes where made. Can include removal of older methods, changes on the API contract or the way parts of the software operates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1.2.0 to 1.3.0:&lt;/strong&gt; New features where added, but all that works in 1.2.0 still works on 1.3.0.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1.2.1 to 1.2.3:&lt;/strong&gt; Bugfixes that don't affect the API or the way user interacts with the software. For example, fixing an error in a function’s logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pre-release Identifiers
&lt;/h2&gt;

&lt;p&gt;Pre-release identifiers can be used to label version that are in experimental or development phase. Pre-release identifiers are written in by adding an hyphen followed by the identifier: &lt;code&gt;&amp;lt;version core&amp;gt; "-" &amp;lt;pre-release identifier&amp;gt; | &amp;lt;pre-release identifier&amp;gt; "." &amp;lt;dot-separated pre-release identifier&amp;gt;&lt;/code&gt;, examples are:  &lt;code&gt;1.0.0-alpha&lt;/code&gt;, &lt;code&gt;1.0.0-beta&lt;/code&gt;, &lt;code&gt;1.0.0-rc&lt;/code&gt; (release candidate), e &lt;code&gt;1.0.0-rc.1&lt;/code&gt;. Note that there are two release candidates for 1.0.0 version. In this case, the precedence is determined by comparing each dot separated identifier from left to right until a difference is found. &lt;/p&gt;

&lt;p&gt;Example: &lt;code&gt;pre-1.0.0-alpha&lt;/code&gt; &amp;lt; &lt;code&gt;1.0.0-alpha.1&lt;/code&gt; &amp;lt; &lt;code&gt;1.0.0-alpha.beta&lt;/code&gt; &amp;lt; &lt;code&gt;1.0.0-beta&lt;/code&gt; &amp;lt; &lt;code&gt;1.0.0-beta.2&lt;/code&gt; &amp;lt; &lt;code&gt;1.0.0-beta.11&lt;/code&gt; &amp;lt; &lt;code&gt;1.0.0-rc.1&lt;/code&gt; &amp;lt; &lt;code&gt;1.0.0&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build Metadata
&lt;/h2&gt;

&lt;p&gt;Build metadata can be added by appending a plus sign followed by dot separated identifiers, for example: &lt;code&gt;1.0.0-rc+011&lt;/code&gt;, &lt;code&gt;1.2.15+20240828092135&lt;/code&gt;, &lt;code&gt;2.0.0-alpha+exp.sha.2604f89&lt;/code&gt;. Build identifiers are &lt;strong&gt;NOT&lt;/strong&gt; taken into account when determining version precedence like pre-release identifiers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Semantic versioning is a powerful tool for managing software releases in a clear and predictable way. By adhering to the principles semantic versioning, developers can communicate the impact of changes to users effectively, ensuring that updates are smooth and manageable. This approach not only helps in maintaining backward compatibility but also fosters a disciplined development process where each release is intentional and well-defined.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://semver.org/" rel="noopener noreferrer"&gt;https://semver.org&lt;/a&gt;&lt;/p&gt;

</description>
      <category>semver</category>
      <category>semantic</category>
      <category>versioning</category>
      <category>github</category>
    </item>
    <item>
      <title>How to Highlight Your GitHub Repositories on LinkedIn</title>
      <dc:creator>Bruno Sartori</dc:creator>
      <pubDate>Fri, 30 Aug 2024 21:31:44 +0000</pubDate>
      <link>https://dev.to/brunosartori/how-to-highlight-your-github-repositories-on-linkedin-pg1</link>
      <guid>https://dev.to/brunosartori/how-to-highlight-your-github-repositories-on-linkedin-pg1</guid>
      <description>&lt;p&gt;&lt;em&gt;by &lt;a href="https://www.linkedin.com/in/bruno-sartori-dev" rel="noopener noreferrer"&gt;Bruno Sartori&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you're a programmer, you've probably thought about posting your GitHub projects on LinkedIn to both enhance your project's visibility and allow recruiters to gain a better understanding of your skills. However, when you post, the visibility of the publication only reaches people for a certain period. It would be interesting if there were a way to add a link to your repository directly on your profile. Well, actually, there is.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Add Your GitHub Repository to LinkedIn in 2 Steps
&lt;/h2&gt;

&lt;p&gt;In this tutorial I’ll show you how I manage to add my repository &lt;a href="https://github.com/bruno-sartori/weeb-logger" rel="noopener noreferrer"&gt;https://github.com/bruno-sartori/weeb-logger&lt;/a&gt; on LinkedIn with two simply steps:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Add a Social Media Card to Your Repository
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to your repository's settings.&lt;/li&gt;
&lt;li&gt;Go to the "Social Preview" section.&lt;/li&gt;
&lt;li&gt;You can download an example template with design guidelines on how to create your image.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flnkq70y3s7e60tka06td.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flnkq70y3s7e60tka06td.png" alt="GitHub Repo Card Template" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After creating your image, click "Edit" to upload it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fef5sahl44nvwdr1nf6lj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fef5sahl44nvwdr1nf6lj.png" alt="Social Preview Image Applied" width="668" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Add a Link to Your Repository on Your LinkedIn Profile
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;On your LinkedIn profile, click the "Add profile section" button.&lt;/li&gt;
&lt;li&gt;Under the "Recommended" tab, click "Add featured."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fswkpfbjxmkt6ydm1jdx5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fswkpfbjxmkt6ydm1jdx5.png" alt="Navigating to Featured section on LinkedIn" width="563" height="500"&gt;&lt;/a&gt;    &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click the "+" button and select "Add a link."&lt;/li&gt;
&lt;li&gt;Enter your repository's URL and click "Add."&lt;/li&gt;
&lt;li&gt;Provide a title and description, then click "Save."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxfijf2fdgmm3frhv5046.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxfijf2fdgmm3frhv5046.png" alt="Adding a Link on LinkedIn" width="752" height="652"&gt;&lt;/a&gt;   &lt;/p&gt;

&lt;p&gt;All set! Now just go back to your profile, and your repository will be in the 'Featured' section.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnucssunftjtygrf4lk1a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnucssunftjtygrf4lk1a.png" alt="Github repository highlighted on LinkedIn" width="800" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;By following these simple steps, you can effectively highlight your GitHub projects directly on your LinkedIn profile. This not only increases the visibility of your work but also allows potential employers and collaborators to easily access and evaluate your skills and contributions. Integrating your GitHub repositories with your LinkedIn profile is a powerful way to showcase your professional portfolio and stand out in the competitive tech industry.&lt;/p&gt;

</description>
      <category>linkedin</category>
      <category>github</category>
      <category>tutorial</category>
      <category>repository</category>
    </item>
  </channel>
</rss>
