<?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: bobby1974</title>
    <description>The latest articles on Forem by bobby1974 (@bobby1974).</description>
    <link>https://forem.com/bobby1974</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%2F2747841%2Fe9edc318-5ba4-4e82-8503-fd31fc126429.png</url>
      <title>Forem: bobby1974</title>
      <link>https://forem.com/bobby1974</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/bobby1974"/>
    <language>en</language>
    <item>
      <title>Complete CI/CD Setup Guide: Automate SaaS Deployment with GitHub Actions</title>
      <dc:creator>bobby1974</dc:creator>
      <pubDate>Wed, 22 Jan 2025 14:19:04 +0000</pubDate>
      <link>https://forem.com/bobby1974/complete-cicd-setup-guide-automate-saas-deployment-with-github-actions-g01</link>
      <guid>https://forem.com/bobby1974/complete-cicd-setup-guide-automate-saas-deployment-with-github-actions-g01</guid>
      <description>&lt;h1&gt;
  
  
  &lt;strong&gt;Complete CI/CD Setup Guide: Automate SaaS Deployment with GitHub Actions&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;This guide provides a &lt;strong&gt;step-by-step&lt;/strong&gt; walkthrough of setting up &lt;strong&gt;Git, GitHub, and CI/CD deployment via FTP&lt;/strong&gt; to automate deployments from your &lt;strong&gt;MacBook to a cPanel server&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;📌 Step 1: Delete Old Files &amp;amp; Start Fresh&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1️⃣ Delete Everything Locally&lt;/strong&gt;
&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;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; ~/Development/master_saas_cbm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;2️⃣ Delete Old Repositories from GitHub&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Go to GitHub → Your repositories → Delete the old repos (&lt;code&gt;master_saas_cbm_*&lt;/code&gt;).&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Confirm deletion.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ &lt;strong&gt;Now we have a clean slate!&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;📌 Step 2: Create a Clean Folder Structure&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;1️⃣ &lt;strong&gt;Create the new project folder:&lt;/strong&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;cd&lt;/span&gt; ~/Development
&lt;span class="nb"&gt;mkdir &lt;/span&gt;master_saas_cbm
&lt;span class="nb"&gt;cd &lt;/span&gt;master_saas_cbm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2️⃣ &lt;strong&gt;Create backend &amp;amp; frontend directories:&lt;/strong&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;backend frontend
&lt;span class="nb"&gt;mkdir &lt;/span&gt;frontend/mobile frontend/web
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3️⃣ &lt;strong&gt;Add &lt;code&gt;.gitkeep&lt;/code&gt; files&lt;/strong&gt; so Git can track these empty 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="nb"&gt;touch &lt;/span&gt;backend/.gitkeep

&lt;span class="nb"&gt;touch &lt;/span&gt;frontend/mobile/.gitkeep

&lt;span class="nb"&gt;touch &lt;/span&gt;frontend/web/.gitkeep
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ &lt;strong&gt;Folder structure is ready!&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;📌 Step 3: Initialize Git in Each Project&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Each part of the project will be a &lt;strong&gt;separate Git repository&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1️⃣ Initialize Git in Backend&lt;/strong&gt;
&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;cd &lt;/span&gt;backend
git init
git branch &lt;span class="nt"&gt;-M&lt;/span&gt; main
git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Initial commit - Backend"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;2️⃣ Initialize Git in Frontend-Web&lt;/strong&gt;
&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;cd&lt;/span&gt; ../frontend/web
git init
git branch &lt;span class="nt"&gt;-M&lt;/span&gt; main
git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Initial commit - Frontend Web"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;3️⃣ Initialize Git in Frontend-Mobile&lt;/strong&gt;
&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;cd&lt;/span&gt; ../mobile
git init
git branch &lt;span class="nt"&gt;-M&lt;/span&gt; main
git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Initial commit - Frontend Mobile"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ &lt;strong&gt;Git is now set up for all three parts!&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;📌 Step 4: Create &amp;amp; Link GitHub Repositories&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now, create &lt;strong&gt;3 separate repositories on GitHub&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;master_saas_cbm_backend&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;master_saas_cbm_frontend_web&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;master_saas_cbm_frontend_mobile&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Connect them to local Git repositories:&lt;/strong&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;For Backend&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/Development/master_saas_cbm/backend
git remote add origin git@github.com:YourUsername/master_saas_cbm_backend.git
git pull origin main &lt;span class="nt"&gt;--allow-unrelated-histories&lt;/span&gt; &lt;span class="nt"&gt;--rebase&lt;/span&gt;
git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;For Frontend-Web&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ../frontend/web
git remote add origin git@github.com:YourUsername/master_saas_cbm_frontend_web.git
git pull origin main &lt;span class="nt"&gt;--allow-unrelated-histories&lt;/span&gt; &lt;span class="nt"&gt;--rebase&lt;/span&gt;
git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;For Frontend-Mobile&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ../mobile
git remote add origin git@github.com:YourUsername/master_saas_cbm_frontend_mobile.git
git pull origin main &lt;span class="nt"&gt;--allow-unrelated-histories&lt;/span&gt; &lt;span class="nt"&gt;--rebase&lt;/span&gt;
git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ &lt;strong&gt;All three projects are now linked to GitHub!&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;📌 Step 5: Add FTP Secrets to GitHub&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Go to GitHub → Your Repository → Settings → Secrets and Variables → Actions&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For &lt;strong&gt;each repository (&lt;code&gt;backend&lt;/code&gt;, &lt;code&gt;frontend-web&lt;/code&gt;, &lt;code&gt;frontend-mobile&lt;/code&gt;)&lt;/strong&gt;, add the following &lt;strong&gt;Repository Secrets&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Secret Name&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Value&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FTP_HOSTNAME&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;yourserver.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FTP_PORT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;21&lt;/code&gt; (for FTP) or &lt;code&gt;22&lt;/code&gt; (for SFTP)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FTP_USERNAME&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Your cPanel FTP username&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FTP_PASSWORD&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Your FTP password&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FTP_SERVER_DIR_BACKEND&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/public_html/backend/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FTP_SERVER_DIR_WEB&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/public_html/frontend_web/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FTP_SERVER_DIR_MOBILE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/public_html/frontend_mobile/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;✅ &lt;strong&gt;Now, GitHub Actions can securely deploy your files via FTP.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;📌 Step 6: Set Up CI/CD for Backend, Frontend-Web &amp;amp; Mobile&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1️⃣ Backend (&lt;code&gt;backend/.github/workflows/deploy.yml&lt;/code&gt;)&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;🚀 Deploy Backend via FTP&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout Code&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy Backend via FTP&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SamKirkland/FTP-Deploy-Action@v4.3.4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;server&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.FTP_HOSTNAME }}&lt;/span&gt;
          &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.FTP_USERNAME }}&lt;/span&gt;
          &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.FTP_PASSWORD }}&lt;/span&gt;
          &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.FTP_PORT }}&lt;/span&gt;
          &lt;span class="na"&gt;local-dir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./&lt;/span&gt;
          &lt;span class="na"&gt;server-dir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.FTP_SERVER_DIR_BACKEND }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;2️⃣ Frontend-Web (&lt;code&gt;frontend-web/.github/workflows/deploy.yml&lt;/code&gt;)&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;🚀 Deploy Frontend-Web via FTP&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout Code&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install Dependencies&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm install&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build React.js App&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run build&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy Web App via FTP&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SamKirkland/FTP-Deploy-Action@v4.3.4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;server&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.FTP_HOSTNAME }}&lt;/span&gt;
          &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.FTP_USERNAME }}&lt;/span&gt;
          &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.FTP_PASSWORD }}&lt;/span&gt;
          &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.FTP_PORT }}&lt;/span&gt;
          &lt;span class="na"&gt;local-dir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./build/&lt;/span&gt;
          &lt;span class="na"&gt;server-dir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.FTP_SERVER_DIR_WEB }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ &lt;strong&gt;Now, backend, frontend-web, and frontend-mobile deploy separately!&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;🚀 &lt;strong&gt;Your CI/CD pipeline is now fully automated! Every time you push to GitHub, your latest code is deployed instantly.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>githubactions</category>
      <category>cicd</category>
      <category>devops</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Automating SaaS Deployment: Automating SaaS Deployment: A Solo Developer’s CI/CD Journey</title>
      <dc:creator>bobby1974</dc:creator>
      <pubDate>Wed, 22 Jan 2025 14:14:10 +0000</pubDate>
      <link>https://forem.com/bobby1974/automating-saas-deployment-automating-saas-deployment-a-solo-developers-cicd-journey-497</link>
      <guid>https://forem.com/bobby1974/automating-saas-deployment-automating-saas-deployment-a-solo-developers-cicd-journey-497</guid>
      <description>&lt;h1&gt;
  
  
  &lt;strong&gt;Automating SaaS Deployment: A Solo Developer’s CI/CD Journey&lt;/strong&gt;
&lt;/h1&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;🚀 The Challenge: The Struggles of Manual Deployment&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;For a long time, my workflow as a solo developer was &lt;strong&gt;completely manual&lt;/strong&gt;. Every time I updated my project, I had to:&lt;/p&gt;

&lt;p&gt;✅ Develop everything on my &lt;strong&gt;MacBook&lt;/strong&gt;&lt;br&gt;
✅ Manually upload backend files via &lt;strong&gt;FileZilla&lt;/strong&gt;&lt;br&gt;
✅ Copy and paste frontend updates into the &lt;strong&gt;public_html&lt;/strong&gt; directory&lt;br&gt;
✅ Worry about &lt;strong&gt;accidentally breaking the website&lt;/strong&gt;&lt;br&gt;
✅ Keep a &lt;strong&gt;local backup&lt;/strong&gt; of my React Native mobile project without versioning&lt;/p&gt;

&lt;p&gt;This worked—but &lt;strong&gt;it was slow, error-prone, and frustrating&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;🔄 Enter Git, GitHub &amp;amp; CI/CD: The Game-Changer&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I wanted to move to &lt;strong&gt;Continuous Integration and Deployment (CI/CD)&lt;/strong&gt; but didn’t know where to start. The idea of &lt;strong&gt;automating deployments&lt;/strong&gt; felt complex. Slowly, a structured plan emerged.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;✅ Step 1: Structuring the Project for Better Organization&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Instead of keeping everything in one place, I created &lt;strong&gt;three separate projects&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;📂 &lt;strong&gt;Backend&lt;/strong&gt; → Handles API requests &amp;amp; database interactions.&lt;br&gt;
📂 &lt;strong&gt;Frontend-Web&lt;/strong&gt; → React.js SaaS website.&lt;br&gt;
📂 &lt;strong&gt;Frontend-Mobile&lt;/strong&gt; → React Native mobile app.&lt;/p&gt;

&lt;p&gt;Each part became its &lt;strong&gt;own GitHub repository&lt;/strong&gt;, so I could update and deploy them &lt;strong&gt;independently&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;🚀 The Breakthrough: Automating Deployment via GitHub Actions&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I wanted my workflow to be as simple as:&lt;br&gt;
✅ &lt;strong&gt;Make changes&lt;/strong&gt;&lt;br&gt;
✅ &lt;strong&gt;Push to GitHub&lt;/strong&gt;&lt;br&gt;
✅ &lt;strong&gt;Files automatically deploy to the server&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;How We Built It:&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Set up Git repositories for backend, frontend-web, and frontend-mobile&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Configured GitHub Actions to handle FTP deployment&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stored credentials securely using GitHub Secrets&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Automated React.js build processes before deployment&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kept the mobile app backed up until it’s ready for the App Store &amp;amp; Play Store&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;📌 The Final Workflow: Simplicity &amp;amp; Power&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now, every time I push my code, the &lt;strong&gt;latest version is automatically deployed&lt;/strong&gt;. No more manual uploads, no more deployment worries!&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Backend updates&lt;/strong&gt; → Automatically deployed via FTP.&lt;br&gt;
✅ &lt;strong&gt;Frontend-web updates&lt;/strong&gt; → Built, then deployed via FTP.&lt;br&gt;
✅ &lt;strong&gt;Frontend-mobile&lt;/strong&gt; → Temporarily stored for backup until final release.&lt;/p&gt;

&lt;p&gt;🚀 &lt;strong&gt;What once took 30-45 minutes per update now happens instantly!&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;💡 A Message to Developers&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;If you’re struggling with &lt;strong&gt;manual deployments&lt;/strong&gt;, this guide will help you &lt;strong&gt;transform your workflow&lt;/strong&gt;. &lt;strong&gt;CI/CD isn’t just for big teams—it’s a lifesaver for solo developers too!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I have also documented the entire &lt;strong&gt;step-by-step process&lt;/strong&gt; of how this CI/CD pipeline was built, including:&lt;br&gt;
✅ Git &amp;amp; GitHub setup&lt;br&gt;
✅ Folder structure for efficient deployment&lt;br&gt;
✅ CI/CD pipeline with GitHub Actions&lt;br&gt;
✅ Automating deployments using FTP&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;Read the full tutorial here:&lt;/strong&gt; [Insert Link to the CI/CD Instructions Post]&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;📌 Helpful Git, GitHub, and CLI Commands for Developers&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;🔹 Git Commands&lt;/strong&gt;
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git init&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Initialize a new Git repository&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git clone &amp;lt;repo-url&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Clone an existing repository&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch -M main&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Rename the current branch to &lt;code&gt;main&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git add .&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stage all changes for commit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git commit -m "message"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Commit changes with a message&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git push origin main&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Push changes to GitHub&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git pull origin main&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pull latest changes from GitHub&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Check the status of your repo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log --oneline&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;View commit history&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git reset --soft HEAD~1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Undo last commit but keep changes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;🔹 GitHub Commands&lt;/strong&gt;
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gh repo create &amp;lt;repo-name&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create a new repository using GitHub CLI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gh auth login&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Authenticate GitHub CLI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gh issue list&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List all issues in a repo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gh pr create&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create a pull request&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gh secret set &amp;lt;name&amp;gt; -b"value"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Add a secret to GitHub Actions&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;🔹 Useful CLI Commands&lt;/strong&gt;
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ls -la&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List files with details&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mkdir &amp;lt;folder-name&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create a new folder&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rm -rf &amp;lt;folder-name&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Delete a folder and its contents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;chmod 755 &amp;lt;file&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Change file permissions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pm2 restart all&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Restart all Node.js applications&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;curl -I &amp;lt;url&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Check if a website is reachable&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;🚀 &lt;strong&gt;These commands will help streamline your development and deployment process Mahaprabhu!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>devops</category>
      <category>cicd</category>
      <category>self</category>
    </item>
  </channel>
</rss>
