<?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: Maksym Kulikovskiy</title>
    <description>The latest articles on DEV Community by Maksym Kulikovskiy (@maxymapp).</description>
    <link>https://dev.to/maxymapp</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%2F443167%2F44eb2fc5-374d-4a8b-b88f-f568107959fc.png</url>
      <title>DEV Community: Maksym Kulikovskiy</title>
      <link>https://dev.to/maxymapp</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/maxymapp"/>
    <language>en</language>
    <item>
      <title>Continuous deployment without dedicated CI/CD tools</title>
      <dc:creator>Maksym Kulikovskiy</dc:creator>
      <pubDate>Thu, 26 Jan 2023 16:38:55 +0000</pubDate>
      <link>https://dev.to/maxymapp/continuous-integration-without-git-hooks-12cm</link>
      <guid>https://dev.to/maxymapp/continuous-integration-without-git-hooks-12cm</guid>
      <description>&lt;p&gt;This article may be interesting to people looking for a quick, albeit limited version (imitation) of a true CI/CD pipeline. Once I had to figure out a way to deploy an app while I was still working with the infra people on configuring our Gitlab CI/CD and Kubernetes stuff.&lt;br&gt;
When it comes to deploying apps, the most basic way is to move the project build to the deployment server and start a server process to serve the build to clients (user machines).&lt;br&gt;
But what if you don't want to &lt;code&gt;ssh&lt;/code&gt; directly into a virtual machine server to deploy an app? Or what if there's a security constraint preventing a direct &lt;code&gt;ssh&lt;/code&gt; connection to a virtual machine server hosting the application? Maybe there's a gateway server in which you have to use CLI  to go to the server of interest (some variety of gatekeeping access I've seen). Instead you'd have to &lt;code&gt;ssh&lt;/code&gt; into another "proxy" server first. Tedious manual process hard to nearly impossible to automate...&lt;/p&gt;

&lt;p&gt;I needed a way to have the app redeploy automatically every time the main/master branches gets updated. [Eventually I did set up Gitlab CI/CD with Docker and Kubernetes]&lt;/p&gt;

&lt;p&gt;I found a workaround.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a &lt;code&gt;deploy.sh&lt;/code&gt; script&lt;/strong&gt; in the project folder of the deployment server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/sh

# add missing PATH env vars for crontab
PATH=/pathtoyournodedir/bin:/usr/bin

cd /usr/share/nginx/myprojectdir/;

git fetch;

LOCAL=$(git rev-parse HEAD);
REMOTE=$(git rev-parse @{u});

if [ $LOCAL != $REMOTE ]; then
    #pull and merge changes
    git pull origin main;

    yarn build;
   # touch "$(date +"%Y_%m_%d_%I_%M_%p").log"
    pm2 restart nextapp

    #change back to home directory
    cd ~;

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

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;#!/bin/sh&lt;/code&gt; line tells it's a bash script to the interpreter.\&lt;/p&gt;

&lt;p&gt;Why &lt;code&gt;PATH=/pathtoyournodedir/bin:/usr/bin&lt;/code&gt; ?&lt;/p&gt;

&lt;p&gt;Here's a good explanation why we had to "import" PATH variables for &lt;code&gt;crontab&lt;/code&gt;: &lt;a href="https://askubuntu.com/a/23438" rel="noopener noreferrer"&gt;https://askubuntu.com/a/23438&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note that it became essential to include PATH for all basic ubuntu utilities like &lt;code&gt;cd&lt;/code&gt; or &lt;code&gt;touch&lt;/code&gt;. I think we're not just adding PATH variables, but rather replacing crontab's default PATH "import" with _only _what we need. Because once I added PATH to &lt;code&gt;node&lt;/code&gt;, it started complaining it didn't know what &lt;code&gt;cd&lt;/code&gt; is :)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd /usr/share/nginx/myprojectdir/;&lt;/code&gt; - go to your project dir - that's where your hidden &lt;code&gt;.git&lt;/code&gt; folder is.&lt;br&gt;
&lt;code&gt;git fetch;&lt;/code&gt; will get the updated list with the latest commits without pulling them in just yet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LOCAL=$(git rev-parse HEAD);
REMOTE=$(git rev-parse @{u});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;gets the latest commit id's to compare to know whether to rebuild.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git pull origin main;&lt;/code&gt; - &lt;code&gt;main&lt;/code&gt; or whatever branch you want to deploy.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;yarn build;&lt;/code&gt; - or however you build your application. Note we can't move the build folder to the server for the above reasons. We do it all on the deployment server.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pm2 restart nextapp&lt;/code&gt; restarts the Node.js process serving the build (if you use &lt;code&gt;pm2&lt;/code&gt;) or however you restart your process.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;# touch "$(date +"%Y_%m_%d_%I_%M_%p").log"&lt;/code&gt; if you remove &lt;code&gt;#&lt;/code&gt; to uncomment the line, it will create a dummy file with the date and time that the script ran to debug cases if the build didn't go through when the script ran.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Make the script executable&lt;/strong&gt; (won't run otherwise):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo chmod u+x rebuild.sh&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Set up a recurring job (script).&lt;/strong&gt;&lt;br&gt;
Run &lt;code&gt;crontab -e&lt;/code&gt; to edit the file with scheduled commands.&lt;br&gt;
Press &lt;code&gt;i&lt;/code&gt; to enter vim edit mode.&lt;br&gt;
Add a line &lt;br&gt;
&lt;code&gt;*/5 * * * * /usr/share/nginx/myprojectdir/rebuild.sh&lt;/code&gt; (will run every 5 min) and press ENTER to go to a new line. (heard a new line was essential)&lt;br&gt;
Press &lt;code&gt;ALT+h&lt;/code&gt; to exit vim edit mode.&lt;br&gt;
Press &lt;code&gt;left SHIFT + :&lt;/code&gt; to bring up command prompt in the bottom left corner of vim editor.&lt;br&gt;
Enter &lt;code&gt;wq&lt;/code&gt; to write and save (or &lt;code&gt;qa&lt;/code&gt; if you simply ever wanted to exit without making changes)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Run &lt;code&gt;crontab -l&lt;/code&gt; to make sure your job has been saved.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wait for 5 min to see if auto deployment happened&lt;/strong&gt; (if needed update interval to 2 min for faster results)&lt;/p&gt;

&lt;p&gt;If deployment didn't happen successfully, but &lt;code&gt;git pull&lt;/code&gt; executed, you need to run &lt;code&gt;git reset --hard HEAD~1&lt;/code&gt; to drop the most recent commit so that the script's &lt;code&gt;if&lt;/code&gt; condition will allow it to run again.&lt;br&gt;
After this build a build manually with &lt;code&gt;yarn build&lt;/code&gt; or similar command to restore the original build if needed (if it got corrupted), so you can await next auto deployment attempt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What code change to make to your project to reflect successful deployment and be able to observe results easily?&lt;/strong&gt; I would recommend a simple UI text change (misspell a word or make some word uppercase)&lt;/p&gt;

&lt;p&gt;Hope this helps! Let me know if you have questions!&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>express</category>
      <category>codenewbie</category>
      <category>networking</category>
    </item>
  </channel>
</rss>
