<?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>Forem: Ravishanker</title>
    <description>The latest articles on Forem by Ravishanker (@ravishanker).</description>
    <link>https://forem.com/ravishanker</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%2F999940%2Fe7df8667-3952-49be-a954-9d889083a0af.jpeg</url>
      <title>Forem: Ravishanker</title>
      <link>https://forem.com/ravishanker</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ravishanker"/>
    <language>en</language>
    <item>
      <title>Tackling Deployment Failures with Git Hooks</title>
      <dc:creator>Ravishanker</dc:creator>
      <pubDate>Thu, 28 Dec 2023 18:49:51 +0000</pubDate>
      <link>https://forem.com/ravishanker/tackling-deployment-failures-with-git-hooks-4gfb</link>
      <guid>https://forem.com/ravishanker/tackling-deployment-failures-with-git-hooks-4gfb</guid>
      <description>&lt;p&gt;It's 3 am and you worked hard to fix a bug/implement a feature and push your commits to GitHub and went to sleep peacefully only to see a failing deployment build email in your inbox when you wake up.  &lt;/p&gt;

&lt;p&gt;If you are someone like me who uses CI/CD to deploy code instead of just pushing the files directly to the production server via SFTP without any VCS, You would have gone through this at least once.&lt;/p&gt;

&lt;p&gt;It can be overcome by using stricter lint configs but will end up with more red squiggly lines in your IDE while doing quick edits, and If you are working on a team not everyone enjoys stricter lint configs for quick edits and ends up not using it anyways.  A better solution to this would be using &lt;strong&gt;Git Hooks&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What are Git Hooks?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Hooks are a way to fire off custom scripts when certain important actions occur.&lt;/em&gt; - Git Documentation&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As the &lt;a href="https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks"&gt;documentation&lt;/a&gt; says we can write our custom scripts that can be triggered when a specific set of actions occur in our repository. These hooks are divided into two types Client-Side Hooks and Server-side Hooks. In this blog, we are going to implement Client-Side hooks.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to implement these hooks?
&lt;/h2&gt;

&lt;p&gt;To implement hooks in a git repository we need to go to &lt;code&gt;.git/hooks/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When we do &lt;code&gt;ls&lt;/code&gt; in this directory we get to see several sample scripts that are present already as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;applypatch-msg.sample&lt;span class="k"&gt;*&lt;/span&gt;      pre-push.sample&lt;span class="k"&gt;*&lt;/span&gt;
commit-msg.sample&lt;span class="k"&gt;*&lt;/span&gt;          pre-rebase.sample&lt;span class="k"&gt;*&lt;/span&gt;
fsmonitor-watchman.sample&lt;span class="k"&gt;*&lt;/span&gt;  pre-receive.sample&lt;span class="k"&gt;*&lt;/span&gt;
post-update.sample&lt;span class="k"&gt;*&lt;/span&gt;         prepare-commit-msg.sample&lt;span class="k"&gt;*&lt;/span&gt;
pre-applypatch.sample&lt;span class="k"&gt;*&lt;/span&gt;      push-to-checkout.sample&lt;span class="k"&gt;*&lt;/span&gt;
pre-commit.sample&lt;span class="k"&gt;*&lt;/span&gt;          sendemail-validate.sample&lt;span class="k"&gt;*&lt;/span&gt;
pre-merge-commit.sample&lt;span class="k"&gt;*&lt;/span&gt;    update.sample&lt;span class="k"&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each of these scripts is executed when the specified action occurs in the repository. The one we are going to see now is &lt;code&gt;pre-push&lt;/code&gt;. This script executes before the commits are pushed to the remote repository.&lt;/p&gt;

&lt;p&gt;Now create a new file called &lt;code&gt;pre-push&lt;/code&gt; and open it in a text editor of your choice. I'm using &lt;code&gt;nvim&lt;/code&gt; here :&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;touch &lt;/span&gt;pre-push &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;chmod&lt;/span&gt; +x pre-push &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; nvim pre-push 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In that script add the following:&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="k"&gt;if &lt;/span&gt;npm run build&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Build successful. Proceeding with push."&lt;/span&gt;
    &lt;span class="nb"&gt;exit &lt;/span&gt;0
&lt;span class="k"&gt;else
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Build failed. Please fix the issues before pushing"&lt;/span&gt;
    &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are running &lt;code&gt;npm run build&lt;/code&gt; (you can change the command if needed) and if it builds successfully we are exiting with &lt;code&gt;exit 0&lt;/code&gt; else exiting with &lt;code&gt;exit 1&lt;/code&gt;. Exiting with a non-zero value in &lt;code&gt;sh&lt;/code&gt; world denotes that the script is executed with errors. Which means the push will not happen.&lt;/p&gt;

&lt;p&gt;So is that it? Not really. If you are the person who just pushes everything to the &lt;code&gt;main&lt;/code&gt; branch then this is done. Otherwise, we need to specify the deployment branch so that this hook runs only when the commits are pushed to that branch. &lt;/p&gt;

&lt;p&gt;To do that we need to find the branch we are currently on. It can be done by using the &lt;code&gt;rev-prase&lt;/code&gt; command in git. However just calling the &lt;code&gt;rev-parse&lt;/code&gt; will return the branch id instead of the name so we need to also add the &lt;code&gt;--abbrev-ref&lt;/code&gt; argument to get the branch name. Now our script will look like this.&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="c"&gt;##!/bin/bash&lt;/span&gt;

&lt;span class="nv"&gt;branch&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;--abbrev-ref&lt;/span&gt; HEAD&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;dep_branch&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"main"&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;$branch&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;$dep_branch&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
    if &lt;/span&gt;npm run build&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Build successful. Proceeding with push."&lt;/span&gt;
        &lt;span class="nb"&gt;exit &lt;/span&gt;0
    &lt;span class="k"&gt;else
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Build failed. Please fix the issues before pushing to the main branch."&lt;/span&gt;
        &lt;span class="nb"&gt;exit &lt;/span&gt;1
    &lt;span class="k"&gt;fi
fi

&lt;/span&gt;&lt;span class="nb"&gt;exit &lt;/span&gt;0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can change the &lt;code&gt;dep_branch&lt;/code&gt; variable to the actual name of your deployment branch.&lt;/p&gt;

&lt;p&gt;So is that it? Yes, but there's more. Optionally we can track changes on specific folders and only do the build if there are changes in specific folders. For example, we don't need to check if the build passes if we just modified your &lt;code&gt;README&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To do that, We need to use the diff command to see if there are changes in the directory we need. In my case, it's the &lt;code&gt;src/&lt;/code&gt; directory.&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="k"&gt;function &lt;/span&gt;are_changes_in_dir &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;local &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;--name-only&lt;/span&gt; origin/main HEAD&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;$changed_files&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;-q&lt;/span&gt; &lt;span class="s2"&gt;"^src/"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternatively, we can write the function like this so that we can track multiple directories.&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="k"&gt;function &lt;/span&gt;are_changes_in_folders &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;folders&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;&lt;span class="s2"&gt;"src/"&lt;/span&gt; &lt;span class="s2"&gt;"lib/"&lt;/span&gt; &lt;span class="s2"&gt;"utils/"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;  &lt;span class="c"&gt;# Add your desired folders to this array&lt;/span&gt;
    &lt;span class="nb"&gt;local &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;--name-only&lt;/span&gt; origin/main HEAD&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;for &lt;/span&gt;folder &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;folders&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
        &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;$changed_files&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;-q&lt;/span&gt; &lt;span class="s2"&gt;"^&lt;/span&gt;&lt;span class="nv"&gt;$folder&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;return &lt;/span&gt;0
    &lt;span class="k"&gt;done

    return &lt;/span&gt;1
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This above function checks if there are any changes in the specified directory. Our final script will look something like this:&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="c"&gt;##!/bin/bash&lt;/span&gt;

&lt;span class="nv"&gt;branch&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;--abbrev-ref&lt;/span&gt; HEAD&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;function &lt;/span&gt;are_changes_in_dir &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;folders&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;&lt;span class="s2"&gt;"src/"&lt;/span&gt; &lt;span class="s2"&gt;"lib/"&lt;/span&gt; &lt;span class="s2"&gt;"utils/"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;  &lt;span class="c"&gt;# Add your desired folders to this array&lt;/span&gt;
    &lt;span class="nb"&gt;local &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;--name-only&lt;/span&gt; origin/main HEAD&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;for &lt;/span&gt;folder &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;folders&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
        &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;$changed_files&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;-q&lt;/span&gt; &lt;span class="s2"&gt;"^&lt;/span&gt;&lt;span class="nv"&gt;$folder&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;return &lt;/span&gt;0
    &lt;span class="k"&gt;done

    return &lt;/span&gt;1
&lt;span class="o"&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;$branch&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"main"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    if &lt;/span&gt;are_changes_in_dir &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Changes detected in the specified directories. Running npm run build..."&lt;/span&gt;

        &lt;span class="k"&gt;if &lt;/span&gt;npm run build&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
            &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Build successful. Proceeding with push."&lt;/span&gt;
            &lt;span class="nb"&gt;exit &lt;/span&gt;0
        &lt;span class="k"&gt;else
            &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Build failed. Please fix the issues before pushing to the main branch."&lt;/span&gt;
            &lt;span class="nb"&gt;exit &lt;/span&gt;1
        &lt;span class="k"&gt;fi
    else
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"No necessary changes detected. Skipping build."&lt;/span&gt;
        &lt;span class="nb"&gt;exit &lt;/span&gt;0
    &lt;span class="k"&gt;fi
fi

&lt;/span&gt;&lt;span class="nb"&gt;exit &lt;/span&gt;0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save this and goodbye to failed deployment builds*&lt;/p&gt;

&lt;p&gt;*Your Team members should also use this hook or else they can push failing commits.&lt;/p&gt;




</description>
      <category>git</category>
      <category>javascript</category>
      <category>productivity</category>
      <category>github</category>
    </item>
    <item>
      <title>A CMS to solve the Stress of Students</title>
      <dc:creator>Ravishanker</dc:creator>
      <pubDate>Sun, 01 Jan 2023 16:10:49 +0000</pubDate>
      <link>https://forem.com/ravishanker/creating-the-learning-oasis-5f7l</link>
      <guid>https://forem.com/ravishanker/creating-the-learning-oasis-5f7l</guid>
      <description>&lt;p&gt;On this new year occasion, I started a new project called SemScape. A learning portal made by students for students. As a measure for Learning and Building in Public&lt;/p&gt;

&lt;h1&gt;
  
  
  Motto of SemScape
&lt;/h1&gt;

&lt;p&gt;The main goal of SemScape is to reduce the friction experienced by students while learning and preparing for semester exams. The name "Sem-Scape" reflects this goal - to provide an escape from the pain of semesters. Many institutions have their own syllabi and patterns for their semesters, making it difficult for students to find relevant materials online. SemScape aims to solve this problem by providing a personalized and centralized place for institutions to manage study materials.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does SemScape achieve this?
&lt;/h2&gt;

&lt;p&gt;One of the key benefits of open source projects is that anyone can fork the code and use it for their own needs. Since SemScape is open source, anyone from any institution can fork the code and host it themselves, as it will be published under the GPL (GNU General Public License).&lt;/p&gt;

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

&lt;p&gt;SemScape is primarily focused on serving colleges and universities. Students will be able to view or download a list of courses and subjects from the site. Behind the scenes, a selected group of contributors from the institution (either faculty members or students) will upload materials and resources for public use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical details for tech-savvy users
&lt;/h2&gt;

&lt;p&gt;SemScape is an open source project that I am building primarily for the purpose of learning and having fun. It will be built using Svelte (a front-end framework) and Supabase (an open source Firebase alternative). As mentioned earlier, SemScape will be published under the GPL.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Mock-Up of current UI design (WIP)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7sX-0WQe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f1v5prprsa0rshzjpkba.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7sX-0WQe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f1v5prprsa0rshzjpkba.png" alt="UI Mock-up (at least better than my institution's UI/UX)" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;This project is currently focused on helping me learn new things by building and solving a problem that exists in my own institution. I hope to improve and potentially scale SemScape in the future. Feel free to drop your Suggestions&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>career</category>
      <category>beginners</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
