<?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: Lenny Zeitoun</title>
    <description>The latest articles on DEV Community by Lenny Zeitoun (@zeitouncorp).</description>
    <link>https://dev.to/zeitouncorp</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%2F767360%2F05e0805e-3b87-40fd-890d-b664b5d19550.jpeg</url>
      <title>DEV Community: Lenny Zeitoun</title>
      <link>https://dev.to/zeitouncorp</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zeitouncorp"/>
    <language>en</language>
    <item>
      <title>How to create your own password generator in under 10 lines of code using NodeJs</title>
      <dc:creator>Lenny Zeitoun</dc:creator>
      <pubDate>Thu, 23 Jun 2022 15:50:16 +0000</pubDate>
      <link>https://dev.to/zeitouncorp/how-to-create-your-own-password-generator-in-under-10-lines-of-code-using-nodejs-3elj</link>
      <guid>https://dev.to/zeitouncorp/how-to-create-your-own-password-generator-in-under-10-lines-of-code-using-nodejs-3elj</guid>
      <description>&lt;h2&gt;
  
  
  Why are we doing this
&lt;/h2&gt;

&lt;p&gt;As we've all noticed lately, websites and apps have become stricter about your account password, which must meet the following minimum requirements: 8 characters long and be a mixture of alpha-numeric characters. Moreover, with latest versions of IOS and Android, they created a whole system where you can find all passwords considered as 'weak' and if one of your password has appeared in a data leak they'll alert you. &lt;br&gt;
I have a saying: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If something already exists but you feel capable of doing it yourself then do it ! &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What I really mean behind this statement is that it doesn't matter that it already exists because the version you have in mind (with all its complexity) doesn't exist, and that's the point: by turning the idea into an application you'll get a better understanding of how things actually work, which will give you not only technical skills but also conversational skills hence giving you the opportunity to teach someone else (which is for me, the most valuable asset in life). &lt;/p&gt;
&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;NodeJs&lt;/code&gt; installed on your computer, if it's not already done, here are the ways to set it up:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simplest solution&lt;/strong&gt;: Using &lt;strong&gt;&lt;a href="https://github.com/nvm-sh/nvm#installing-and-updating"&gt;nvm&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;From official source&lt;/strong&gt;: You can download it from &lt;strong&gt;&lt;a href="https://nodejs.org/en/"&gt;here&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Using a packet manager&lt;/strong&gt;: &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using apt-get&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;# The first step is to update your system&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update

&lt;span class="c"&gt;# Then run&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;nodejs
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;npm

&lt;span class="c"&gt;# Finally test installation using&lt;/span&gt;
&lt;span class="c"&gt;# It should output the currently installed version of node &amp;amp; npm&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;node &lt;span class="nt"&gt;-v&lt;/span&gt; 
&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using Homebrew&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;# The first step is to update your brew local cache&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;brew update

&lt;span class="c"&gt;# Then run, it will install both nodejs and npm at the same time&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;node 

&lt;span class="c"&gt;# Finally test installation using&lt;/span&gt;
&lt;span class="c"&gt;# It should output the currently installed version of node &amp;amp; npm&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;node &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;First things first we are going to create a new file in our &lt;code&gt;bin&lt;/code&gt; folder, I decided to use the one located at &lt;code&gt;~/.bin&lt;/code&gt;, doing so will let you call our password generator script from anywhere you want. &lt;/p&gt;

&lt;p&gt;I am assuming that the &lt;code&gt;~/.bin/&lt;/code&gt; is already registered and exported in your global environment variable &lt;code&gt;$PATH&lt;/code&gt;. If not, then heads up to your terminal, &lt;code&gt;mkdir ~/.bin&lt;/code&gt;, then edit your shell configuration file ( egc: &lt;code&gt;~/.bashrc&lt;/code&gt;, &lt;code&gt;~/.bash_profile&lt;/code&gt;, &lt;code&gt;~/.zshrc&lt;/code&gt;, &lt;code&gt;~/.zsh_profile&lt;/code&gt;...) by happening at the end of it &lt;code&gt;export PATH=$PATH:~/.bin&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once this is done, heads up to our &lt;code&gt;~/.bin/&lt;/code&gt; folder and create a file using &lt;code&gt;touch&lt;/code&gt; command, let's call it &lt;code&gt;createPassword&lt;/code&gt;.&lt;br&gt;
Now, open the file in your favorite code editor, I'll personally use &lt;code&gt;VsCode&lt;/code&gt; by doing &lt;code&gt;code ./createPassword&lt;/code&gt;. If everything is set up correctly you should have a blank page by now named after the file you created earlier, now let's dive in the code for our password generator.&lt;/p&gt;
&lt;h2&gt;
  
  
  The script
&lt;/h2&gt;

&lt;p&gt;As you may know, NodeJs has a powerful builtin cryptographic library called crypto, let's import it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;crypto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;To make sure your installation of node is working I suggest you to run &lt;code&gt;node NAME_OF_THE_SCRIPT&lt;/code&gt;, if it doesn't throw any error then you are all settle.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, what we are looking for in a password generator is its strength and robustness. We can simplify that concept by assuming that the longer it is the better. We then need a way to tell the generator how long we want the output password to be ? In our case we will use arguments. Now add this line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;We slice the arguments received in order to extract the custom 'parameters' (in our case, a number that we will call 'length')&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now we can create a variable in our script, called &lt;code&gt;length&lt;/code&gt;. Its value will be equal to the Number we pass to our script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note that we cast our argument to &lt;code&gt;Number&lt;/code&gt; because when we receive it from the terminal it's of type &lt;code&gt;String&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Next and last step is to check if our parsed number return a number and not an error (or NaN). If so, we simply call the crypto library and generate a random password else we alert the user that he didn't pass a correct parameter to the script. The condition looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&lt;/span&gt;&lt;span class="dl"&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="nb"&gt;isNaN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;randomBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pass&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// No errors&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error: Param must be of type number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Error&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we put everything together, our script should look like this:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cmSCz0we--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4o1kmy8k54fwnrkupkny.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cmSCz0we--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4o1kmy8k54fwnrkupkny.png" alt="Script content" width="880" height="708"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, that's it, hope you'll enjoy this small tutorial on how to create a password generator in under 10 lines of code using NodeJs.&lt;br&gt;
'Till next time 😉.&lt;/p&gt;

&lt;h3&gt;
  
  
  A little bit more about me:
&lt;/h3&gt;

&lt;p&gt;I'm Lenny, senior software engineer, Founder of &lt;strong&gt;&lt;a href="https://www.linkedin.com/company/zeitouncorporate/"&gt;ZCorp&lt;/a&gt;&lt;/strong&gt; focused on Consulting for helping people to develop and grow their ideas into a reliable, rewarding and profitable business. &lt;br&gt;
Here are some links to my networks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://github.com/ZeitounCorp"&gt;GitHub&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://www.linkedin.com/in/lenny-zeitoun/"&gt;Linkedin&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://dev.to/zeitouncorp"&gt;Dev.to&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>password</category>
      <category>node</category>
      <category>crypto</category>
      <category>shell</category>
    </item>
    <item>
      <title>How to improve the efficiency of git commits in a remote team ?</title>
      <dc:creator>Lenny Zeitoun</dc:creator>
      <pubDate>Thu, 03 Mar 2022 18:34:19 +0000</pubDate>
      <link>https://dev.to/zeitouncorp/how-to-improve-the-efficiency-of-git-commits-in-a-remote-team--pbn</link>
      <guid>https://dev.to/zeitouncorp/how-to-improve-the-efficiency-of-git-commits-in-a-remote-team--pbn</guid>
      <description>&lt;h2&gt;
  
  
  Why this article
&lt;/h2&gt;

&lt;p&gt;As we dive further into 2022, I thought it was a good time to make a recap of 2021 in terms of tools and technologies that I've put in place as a CTO in a growing (startup) agency. &lt;/p&gt;

&lt;p&gt;Covid-19 has, for sure, been a rough time. People had to re-think their infrastructures, how they work, how they communicate and more basically, how they interact and stay organized while being in quarantine. But because of that, it brought new challenges and thus, new opportunities to startup like ours.&lt;/p&gt;

&lt;h2&gt;
  
  
  Communication is the key
&lt;/h2&gt;

&lt;p&gt;When it comes to organization in a team, most of the time, problems come from a lack of (efficient) communication. &lt;br&gt;
For example, when managing multiple projects at once or working with developers around the world using different technology stacks, you are required to be as thorough as possible in order to keep track of what have been/need to be done. Here starts the problem, even though you can be extremely organized (I've, myself, been using dozen of apps for this kind of purpose, I'll publish an article later on my thoughts &amp;amp; findings), &lt;strong&gt;if only one link in the chain lacks rigor, the entire organization is compromised&lt;/strong&gt; !&lt;/p&gt;
&lt;h2&gt;
  
  
  My take on 'cutting the man in the middle'
&lt;/h2&gt;

&lt;p&gt;As logical as it is, when you need to rely on someone else, you become dependent on his skills and organizational system, thus, if he misses to keep in touch with you about his latest achievements (egc: push on a git repo to fix a bug, new feature, pull request...), there is an impact on the time it takes to accomplish common actions (code review, merging features).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LMLHn4YB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t9a21jj691ba0yd74u87.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LMLHn4YB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t9a21jj691ba0yd74u87.png" alt="schema representing what a feature integration" width="880" height="608"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Here is a schema representing what a feature integration looks like with the given problematic&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When I understood that I could not control how other human being manage their time and organization, I asked myself 'What can I do to fix this ?', the answer was pretty obvious, I needed to create kind of a bot, acting as an intermediary between me and the developers.&lt;br&gt;
&lt;strong&gt;Well, as you can see, it's not so much about cutting the man in the middle but replacing the man by the bot !&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Wed1WvI6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ceyk1zf8cyn7d88p2xia.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Wed1WvI6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ceyk1zf8cyn7d88p2xia.png" alt="Here is a schema with optimized workflow" width="880" height="608"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Here is the schema representing the optimized workflow using the bot I created as a replacement for the human (report) interaction &lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Creating the perfect assistant
&lt;/h2&gt;

&lt;p&gt;The following list contains (mostly) all the informations I'm looking for when one of our developers make a commit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User making the commit&lt;/li&gt;
&lt;li&gt;Commit date (localized) &lt;/li&gt;
&lt;li&gt;Get a clear report on what have been done.&lt;/li&gt;
&lt;li&gt;Which type of modifications we are looking at (feature integration, bug fix...).&lt;/li&gt;
&lt;li&gt;Which files have been edited.&lt;/li&gt;
&lt;li&gt;Number of modifications, number of changes (additions/deletions)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Github action workflow
&lt;/h2&gt;

&lt;p&gt;With these informations, I can do the technical review efficiently, mainly because I know what I'm looking at and what I need to pay attention to.&lt;br&gt;
Based on these criteria, I started building my Github action and this is the workflow I've come to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A developer makes a commit to one of our repos, triggering the Github action.&lt;/li&gt;
&lt;li&gt;The action processes the infos extracted from the commit&lt;/li&gt;
&lt;li&gt;It then generates a comment on the given commit with the following infos: &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UoB-mDYe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/84ubs3bj7jqz8785ihgf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UoB-mDYe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/84ubs3bj7jqz8785ihgf.png" alt="Github action example commit's comment" width="880" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At the same time, it triggers an event for sending an email to the repositories' designated maintainers that looks like that: &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lmQvLqmn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b7slv718jt9euexxh28x.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lmQvLqmn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b7slv718jt9euexxh28x.jpeg" alt="Mail received from the Github action on new commit" width="880" height="1545"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;As you can see, with this process, we receive live the infos we need from the developers without the need of a human report.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Not only did it halve the time needed for technical code review, but it completely eliminated the need to ask developers to "Don't forget to send your report". &lt;br&gt;
You are pleased to use it in your projects, I'm sure that it will help you or your team to be more productive hence having the time for the things that matter the most.&lt;br&gt;
For all configuration options and parameters available for the Github action, you are welcome to take a look at the repository (link below).&lt;br&gt;
Hope you enjoy ! &lt;br&gt;
Leave a star on the repo if you find it helpful (and drop a comment on this article to tell me what you think about it)&lt;br&gt;
See you next time !&lt;/p&gt;
&lt;h2&gt;
  
  
  The repository: Git-Push-metadata-action
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--566lAguM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/ZeitounCorp"&gt;
        ZeitounCorp
      &lt;/a&gt; / &lt;a href="https://github.com/ZeitounCorp/Git-Push-metadata-action"&gt;
        Git-Push-metadata-action
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Github action that should execute when a new push happens on a repository, should alert the maintainer by mail with the number of files modified, number of modifications, full date (DD/MM/YYYY @ time) 
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Git-Push-metadata-action&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;Github action that should execute when a new push happens on a repository, should alert the maintainer by mail with the number of files modified, number of modifications, full date (DD/MM/YYYY @ time) and the commit message&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
How to use it&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Open an existing repository or create a new one&lt;/li&gt;
&lt;li&gt;Add the action to your workflow (inside &lt;code&gt;.github/workflows/&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Create the GitHub Secrets required for running the action (&lt;code&gt;Settings &amp;gt; Secrets &amp;gt; Actions &amp;gt; New repository secret&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Enjoy detailed notifications on your repository when a new push happens !&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
Action configuration file (.yaml)&lt;/h2&gt;
&lt;div class="highlight highlight-source-yaml notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-ent"&gt;name&lt;/span&gt;: &lt;span class="pl-s"&gt;Git commit metadata annotation&lt;/span&gt;
&lt;span class="pl-ent"&gt;on&lt;/span&gt;: &lt;span class="pl-s"&gt;push&lt;/span&gt;

&lt;span class="pl-ent"&gt;jobs&lt;/span&gt;:
  &lt;span class="pl-ent"&gt;annotate-pr&lt;/span&gt;:
    &lt;span class="pl-ent"&gt;runs-on&lt;/span&gt;: &lt;span class="pl-s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="pl-ent"&gt;name&lt;/span&gt;: &lt;span class="pl-s"&gt;Annotates commits with metadata&lt;/span&gt;
    &lt;span class="pl-ent"&gt;steps&lt;/span&gt;:
      &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; - uses: hmarr/debug-action@v2 uncomment to debug&lt;/span&gt;
      - &lt;span class="pl-ent"&gt;name&lt;/span&gt;: &lt;span class="pl-s"&gt;Annotate Commit&lt;/span&gt;
        &lt;span class="pl-ent"&gt;uses&lt;/span&gt;: &lt;span class="pl-s"&gt;ZeitounCorp/Git-Push-metadata-action@main&lt;/span&gt;
        &lt;span class="pl-ent"&gt;with&lt;/span&gt;:
          &lt;span class="pl-ent"&gt;owner&lt;/span&gt;: &lt;span class="pl-s"&gt;${{ github.repository_owner }} &lt;/span&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Owner of the repository&lt;/span&gt;
          &lt;span class="pl-ent"&gt;repo&lt;/span&gt;: &lt;span class="pl-s"&gt;${{&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/ZeitounCorp/Git-Push-metadata-action"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  A little bit more about me:
&lt;/h3&gt;

&lt;p&gt;I'm Lenny, (ex) software engineer, now CTO in a growing startup (called &lt;a href="https://www.linkedin.com/company/tsohar-agency/"&gt;Tsohar&lt;/a&gt;) focused on Consulting for helping people to develop and grow their ideas into a reliable, rewarding and profitable business. &lt;br&gt;
Here are some links to my networks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ZeitounCorp"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/lenny-zeitoun/"&gt;Linkedin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/zeitouncorp"&gt;Dev.to&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>git</category>
      <category>github</category>
      <category>actions</category>
    </item>
    <item>
      <title>What's taking so much storage on a dev computer ?(and how to fix it !)</title>
      <dc:creator>Lenny Zeitoun</dc:creator>
      <pubDate>Wed, 19 Jan 2022 11:30:05 +0000</pubDate>
      <link>https://dev.to/zeitouncorp/whats-taking-so-much-storage-on-a-dev-computer-and-how-to-fix-it--3il7</link>
      <guid>https://dev.to/zeitouncorp/whats-taking-so-much-storage-on-a-dev-computer-and-how-to-fix-it--3il7</guid>
      <description>&lt;h2&gt;
  
  
  Why this article
&lt;/h2&gt;

&lt;p&gt;Hi everyone, today I want to talk about something that I just discovered after 10 years in the dev industry (as a software engineer). Until now, I wasn't the kind of person looking after the 'remaining disk space', but as I logged into my computer this morning, &lt;strong&gt;an alert popped up&lt;/strong&gt;, telling me that &lt;strong&gt;I needed to free some disk space because I was running low&lt;/strong&gt;. So here started my investigation !&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;So first things first, I needed something to visualize what was taking space on my computer. &lt;br&gt;
As anyone would have done, I used the builtin storage visualizer available on my computer, but here started the problems. Builtin tools like that are limited, most of the time, they only try to give you an overview of your storage usage by grouping your files, applications, photos into bigger categories (like Documents, Apps...) and there is the problem, if a file doesn't fit the predefined category schema, then it falls into a global category called 'Other files' and you can't know which files are concerned by this 'filter'.&lt;br&gt;
As a developer (and absolute console interface lover), I tried the good old way: &lt;code&gt;du -h /path/to/folder&lt;/code&gt;, but as you can imagine this would have take a lot of time and an extensive knowledge of my computer folders and files architecture (which with all these years is starting to get a little bit messy)&lt;/p&gt;

&lt;h2&gt;
  
  
  The right tools bring great insights
&lt;/h2&gt;

&lt;p&gt;So after long hours shelling my storage space, I decided to change my technique and I went online looking for a tool that could help in this time consuming task, few came up:&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%2Fs4r1gdjxb6jeumcbmsk6.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%2Fs4r1gdjxb6jeumcbmsk6.png" alt="CleanMyMac interface"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CleanMyMac&lt;/strong&gt; or &lt;strong&gt;CleanMyPC&lt;/strong&gt; (for Windows' users). Fantastic interface, super simple to use and a panel of functionalities that exceeds by far all other known software in this category. But such capacities come for a price and for such a small task as finding what took so much space on my computer I wanted to find a free tool. I might be interested one day in paying a subscription for the kind of features that CleanMyMac proposes, but for now I need to find another tool.&lt;/li&gt;
&lt;/ul&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%2Fs36oblp9wbv83w9k5x48.jpeg" 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%2Fs36oblp9wbv83w9k5x48.jpeg" alt="DaisyDisk interface"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DaisyDisk&lt;/strong&gt;: Even though it's not free, it was worth mentioning this software because of it's trial plan. It comes as a simple interface with on the left side an interactive colorful wheel that helps you navigate through your computer's folders and on the right side you can see the files located in the currently selected 'folder'. The free plan will for sure help you sweep away useless data but it's limited thus not interesting for our case.&lt;/li&gt;
&lt;/ul&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%2F79rd4iloavmqvkk57m1m.jpeg" 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%2F79rd4iloavmqvkk57m1m.jpeg" alt="OmniDiskSweeper interface"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OmniDiskSweeper&lt;/strong&gt;: Last arrow in my quiver, it is the one I was looking for: &lt;strong&gt;completely free&lt;/strong&gt;, great user interface (that reminds me of the Finder), boosted on steroids when it comes to calculate the weight of your computer's folders. He is a hole in one for me.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My Discoveries
&lt;/h2&gt;

&lt;p&gt;So if you are like me, you don't restart that often your computer and because of it caches' folders are getting bigger and bigger over time. As an example my computer Cache folder was taking 8 GB of storage. But that is nothing compare to my next discovery. When looking through &lt;strong&gt;OmniDiskSweeper&lt;/strong&gt;, I've found out that the folder located at &lt;code&gt;~/.npm/_cacache&lt;/code&gt; was taking 20GB of storage. It's the result of years of &lt;code&gt;npm install&lt;/code&gt; commands that kept building some secure backups of libraries that I used for my different projects as an 'integrity package validator'. I had no choice: I needed to clear that cache but I needed to be cautious, I didn't want to compromise my node and npm installation.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to fix your npm consuming storage problem
&lt;/h2&gt;

&lt;p&gt;Simple enough, when you look at npm's documentation there is an interesting command &lt;code&gt;npm cache verify&lt;/code&gt; that is supposed to check and compress your npm cache data. After doing as told, the cache reduced to 17GB but it still was too much. I decided to use another command: &lt;code&gt;npm cache clean&lt;/code&gt;. As you can understand, by executing this command it will delete the _cacache folder's content, thus claiming back our 17GB storage space. If you try to run this command as of npm@5 you should get the following error:&lt;/p&gt;

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

npm ERR! As of npm@5, the npm cache self-heals from corruption issues and data extracted from the cache is guaranteed to be valid. If you want to make sure everything is consistent, use &lt;span class="s1"&gt;'npm cache verify'&lt;/span&gt; instead. On the other hand, &lt;span class="k"&gt;if &lt;/span&gt;you&lt;span class="s1"&gt;'re debugging an issue with the installer, you can use `npm install --cache /tmp/empty-cache` to use a temporary cache instead of nuking the actual one.
npm ERR! 
npm ERR! If you'&lt;/span&gt;re sure you want to delete the entire cache, rerun this &lt;span class="nb"&gt;command &lt;/span&gt;with &lt;span class="nt"&gt;--force&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;

npm ERR! A &lt;span class="nb"&gt;complete &lt;/span&gt;log of this run can be found &lt;span class="k"&gt;in&lt;/span&gt;:
npm ERR!     ~/.npm/_logs/2022-01-19T10_45_45_597Z-debug.log


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

&lt;/div&gt;

&lt;p&gt;No worries, as they tell you on npm's documentation website the reason for this error is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;npm stores cache data in an opaque directory within the configured cache, named _cacache. This directory is a &lt;code&gt;cacache-based&lt;/code&gt; content-addressable cache that stores all http request data as well as other package-related data. This directory is primarily accessed through &lt;code&gt;pacote&lt;/code&gt;, the library responsible for all package fetching as of &lt;code&gt;npm@5&lt;/code&gt;.&lt;br&gt;
All data that passes through the cache is fully verified for integrity on both insertion and extraction. Cache corruption will either trigger an error, or signal to &lt;code&gt;pacote&lt;/code&gt; that the data must be refetched, which it will do automatically.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;So what do we do ?&lt;/strong&gt;&lt;br&gt;
As they tell us: if we are looking for reclaiming storage space we can run the command &lt;code&gt;npm cache clean&lt;/code&gt; with the parameter &lt;code&gt;--force&lt;/code&gt; in order to overrule this new 'security' that came with &lt;a href="mailto:npm@5"&gt;npm@5&lt;/a&gt;. So the command becomes: &lt;code&gt;npm cache clean --force&lt;/code&gt;.&lt;br&gt;
After execution, you should see that all the storage eaten up by npm cache should be restored and that's how, by deleting my computer old caches's folders I claimed back more than &lt;strong&gt;30GB&lt;/strong&gt; of storage.&lt;/p&gt;

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

&lt;p&gt;As you can see, most of the time we are missing crucial informations when it comes to managing storage on our computers. Even though the size of our HDD or SSD is getting bigger, the programs, applications and tools we use are also getting bigger and bigger. By getting the right storage analysis tool, we can definitely claim back a lot of storage without the hassle of figuring out what is taking so much space on our computers.&lt;br&gt;
If you liked this (first) article, please consider letting a like or a comment, t will for sure help me making more and better content.&lt;br&gt;
Hope you enjoyed !&lt;br&gt;
See you next time &lt;/p&gt;

&lt;h3&gt;
  
  
  Useful links
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://macpaw.com/cleanmymac" rel="noopener noreferrer"&gt;CleanMyMac&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://macpaw.com/cleanmypc" rel="noopener noreferrer"&gt;CleanMyPC&lt;/a&gt; (to note that they are no longer maintaining nor updating this app)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://daisydiskapp.com/" rel="noopener noreferrer"&gt;DaisyDisk&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.omnigroup.com/more" rel="noopener noreferrer"&gt;OmniDiskSweeper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://osxdaily.com/2016/04/29/best-disk-storage-analyzers-mac/" rel="noopener noreferrer"&gt;OSXDaily article on useful storage manager tools&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  A little bit more about me:
&lt;/h3&gt;

&lt;p&gt;I'm Lenny, ex software engineer, now CTO in a growing startup focused on Consulting for helping people to develop and grow their ideas into a reliable, rewarding and profitable business. &lt;br&gt;
Here are some links to my networks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ZeitounCorp" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/lenny-zeitoun/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/zeitouncorp"&gt;Dev.to&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>npm</category>
      <category>node</category>
      <category>terminal</category>
      <category>storage</category>
    </item>
  </channel>
</rss>
