<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Vscode on</title><link>https://augmentedresilience.com/tags/vscode/</link><description>Recent content in Vscode on</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Sun, 15 Feb 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://augmentedresilience.com/tags/vscode/index.xml" rel="self" type="application/rss+xml"/><item><title>Deploying a Hugo Site to Namecheap with PAI</title><link>https://augmentedresilience.com/posts/augmented-resilience-posts/deploying-a-hugo-site-to-namecheap-with-pai/</link><pubDate>Sun, 15 Feb 2026 00:00:00 +0000</pubDate><guid>https://augmentedresilience.com/posts/augmented-resilience-posts/deploying-a-hugo-site-to-namecheap-with-pai/</guid><description>&lt;p>I recently deployed my Hugo blog to Namecheap shared hosting, using Obsidian as my content editor and Claude Code with PAI (Personal AI) as my copilot. Here&amp;rsquo;s a walkthrough of every step, from fixing build errors to setting up a fully automated pipeline that goes from Obsidian to live site in a single command.&lt;/p>
&lt;h2 id="the-starting-point">The Starting Point&lt;/h2>
&lt;p>I created a Hugo blog project called &lt;strong>Augmented Resilience&lt;/strong> and used the &lt;a href="https://github.com/mirus-ua/hugo-theme-re-terminal" target="_blank" rel="noopener noreferrer">re-terminal&lt;/a>
theme, a Namecheap shared hosting account, and a GitHub repository. I used Claude Code in VS Code editor and leveraged Daniel Miessler&amp;rsquo;s Personal AI infrastructure. The goal: get the site live at &lt;a href="https://augmentedresilience.com" target="_blank" rel="noopener noreferrer">augmentedresilience.com&lt;/a>
with a push-to-deploy workflow.&lt;/p></description><content>&lt;p>I recently deployed my Hugo blog to Namecheap shared hosting, using Obsidian as my content editor and Claude Code with PAI (Personal AI) as my copilot. Here&amp;rsquo;s a walkthrough of every step, from fixing build errors to setting up a fully automated pipeline that goes from Obsidian to live site in a single command.&lt;/p>
&lt;h2 id="the-starting-point">The Starting Point&lt;/h2>
&lt;p>I created a Hugo blog project called &lt;strong>Augmented Resilience&lt;/strong> and used the &lt;a href="https://github.com/mirus-ua/hugo-theme-re-terminal" target="_blank" rel="noopener noreferrer">re-terminal&lt;/a>
theme, a Namecheap shared hosting account, and a GitHub repository. I used Claude Code in VS Code editor and leveraged Daniel Miessler&amp;rsquo;s Personal AI infrastructure. The goal: get the site live at &lt;a href="https://augmentedresilience.com" target="_blank" rel="noopener noreferrer">augmentedresilience.com&lt;/a>
with a push-to-deploy workflow.&lt;/p>
&lt;p>For context, the Personal AI Infrastructure System (PAI) from Daniel Miessler (see resources below) is an open-source framework that wraps around Claude Code and turns it into a structured problem-solving system. Instead of just chatting with an AI, PAI runs every request through a 7-phase algorithm — observe, think, plan, build, execute, verify, learn — so nothing gets skipped. It maintains persistent memory across sessions (so it remembers my project structure, preferences, and past decisions), automatically selects specialized agents for different tasks (security review, architecture, engineering), and enforces verification criteria before declaring anything &amp;ldquo;done.&amp;rdquo; For this project, PAI handled everything from debugging Hugo build errors to writing the deploy script to catching sensitive data I accidentally left in this blog post before it went live. It wasn&amp;rsquo;t just an AI assistant — it was the entire workflow engine. I found it easier to use it within VS Code (&lt;em>still getting used to using the command line interface&lt;/em>).&lt;/p>
&lt;h2 id="step-1-fixing-the-hugo-build">Step 1: Fixing the Hugo Build&lt;/h2>
&lt;p>The first issue was a build error:&lt;/p>
&lt;pre tabindex="0">&lt;code>module &amp;#34;hugo-theme-re-terminal&amp;#34; not found
&lt;/code>&lt;/pre>&lt;p>The problem was a mismatch between the theme name in &lt;code>hugo.toml&lt;/code> and the actual directory name. The theme was installed as a git submodule at &lt;code>themes/re-terminal/&lt;/code>, but the config referenced &lt;code>hugo-theme-re-terminal&lt;/code>.&lt;/p>
&lt;p>&lt;strong>Fix:&lt;/strong> Change the theme name in &lt;code>hugo.toml&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-toml" data-lang="toml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">theme&lt;/span> = &lt;span style="color:#e6db74">&amp;#34;re-terminal&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>After that, &lt;code>hugo&lt;/code> built the site successfully, generating the &lt;code>public/&lt;/code> folder with all the static files.&lt;/p>
&lt;h2 id="step-2-setting-up-the-github-repository">Step 2: Setting Up the GitHub Repository&lt;/h2>
&lt;p>I initialized the repo and connected it to GitHub:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>git init
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>git remote add origin git@github.com:dsacosta/Augmented-Resilience.git
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>git add .
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>git commit -m &lt;span style="color:#e6db74">&amp;#34;my first commit&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>git push origin main
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>One gotcha: I initially typed &lt;code>orgin&lt;/code> instead of &lt;code>origin&lt;/code> in the remote add command. Typos happen — double-check your remote names with &lt;code>git remote -v&lt;/code>.&lt;/p>
&lt;h2 id="step-3-connecting-namecheap-to-github-via-ssh">Step 3: Connecting Namecheap to GitHub via SSH&lt;/h2>
&lt;p>This was the trickiest part. Namecheap shared hosting needs an SSH key to clone from a private GitHub repo. Here&amp;rsquo;s what worked:&lt;/p>
&lt;h3 id="generate-an-ssh-key-on-namecheap">Generate an SSH Key on Namecheap&lt;/h3>
&lt;ol>
&lt;li>Log into &lt;strong>cPanel&lt;/strong> on Namecheap&lt;/li>
&lt;li>Go to &lt;strong>SSH Access&lt;/strong> → &lt;strong>Manage SSH Keys&lt;/strong> → &lt;strong>Generate a New Key&lt;/strong>&lt;/li>
&lt;li>Generate an RSA key (I used the default settings)&lt;/li>
&lt;/ol>
&lt;h3 id="remove-the-passphrase">Remove the Passphrase&lt;/h3>
&lt;p>This is critical. cPanel&amp;rsquo;s Git Version Control runs non-interactively, so it can&amp;rsquo;t prompt for a passphrase. I opened &lt;strong>cPanel Terminal&lt;/strong> and ran:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>ssh-keygen -p -f ~/.ssh/id_rsa
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Enter the old passphrase, then press Enter twice for no new passphrase.&lt;/p>
&lt;h3 id="add-the-public-key-to-github">Add the Public Key to GitHub&lt;/h3>
&lt;ol>
&lt;li>On Namecheap&amp;rsquo;s cPanel Terminal, run: &lt;code>cat ~/.ssh/id_rsa.pub&lt;/code>&lt;/li>
&lt;li>Copy the output&lt;/li>
&lt;li>Go to your GitHub repo → &lt;strong>Settings&lt;/strong> → &lt;strong>Deploy Keys&lt;/strong> → &lt;strong>Add deploy key&lt;/strong>&lt;/li>
&lt;li>Paste the public key and save&lt;/li>
&lt;/ol>
&lt;h3 id="verify-the-connection">Verify the Connection&lt;/h3>
&lt;p>From cPanel Terminal:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>ssh -T git@github.com
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>You should see: &lt;code>Hi dsacosta/Augmented-Resilience! You've successfully authenticated...&lt;/code>&lt;/p>
&lt;h2 id="step-4-clone-the-repo-on-namecheap">Step 4: Clone the Repo on Namecheap&lt;/h2>
&lt;ol>
&lt;li>In cPanel, go to &lt;strong>Git Version Control&lt;/strong> → &lt;strong>Create&lt;/strong>&lt;/li>
&lt;li>Toggle &lt;strong>Clone a Repository&lt;/strong> on&lt;/li>
&lt;li>Enter the clone URL: &lt;code>git@github.com:dsacosta/Augmented-Resilience.git&lt;/code>&lt;/li>
&lt;li>Set the repository path (I used &lt;code>/home/yourusername/your-repo&lt;/code>)&lt;/li>
&lt;li>Click &lt;strong>Create&lt;/strong>&lt;/li>
&lt;/ol>
&lt;p>Important: Don&amp;rsquo;t clone directly into &lt;code>public_html&lt;/code> or your domain folder — it likely already has files and will error out. Clone to a separate directory and use deployment to copy files over.&lt;/p>
&lt;h2 id="step-5-auto-deployment-with-cpanelyml">Step 5: Auto-Deployment with .cpanel.yml&lt;/h2>
&lt;p>cPanel supports automatic deployment tasks via a &lt;code>.cpanel.yml&lt;/code> file in the repo root. This file tells cPanel what to do after each pull:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>---
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">deployment&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">tasks&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">export DEPLOYPATH=/home/yourusername/yourdomain.com/&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">/bin/cp -R public/* $DEPLOYPATH&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This copies everything from the &lt;code>public/&lt;/code> folder (Hugo&amp;rsquo;s build output) into the live site directory.&lt;/p>
&lt;p>After pushing this file to GitHub:&lt;/p>
&lt;ol>
&lt;li>Go to &lt;strong>Git Version Control&lt;/strong> → &lt;strong>Manage&lt;/strong> your repo&lt;/li>
&lt;li>Click the &lt;strong>Pull or Deploy&lt;/strong> tab&lt;/li>
&lt;li>Click &lt;strong>Update from Remote&lt;/strong> to pull the latest&lt;/li>
&lt;li>Click &lt;strong>Deploy HEAD Commit&lt;/strong> to trigger the &lt;code>.cpanel.yml&lt;/code> tasks&lt;/li>
&lt;/ol>
&lt;p>Your site should now be live.&lt;/p>
&lt;h2 id="step-6-fully-automated-deploys-with-github-actions">Step 6: Fully Automated Deploys with GitHub Actions&lt;/h2>
&lt;p>To eliminate the manual &amp;ldquo;pull and deploy&amp;rdquo; step in cPanel, I set up a GitHub Actions workflow that SSHs into Namecheap and triggers the pull automatically on every push.&lt;/p>
&lt;h3 id="generate-a-deploy-key">Generate a Deploy Key&lt;/h3>
&lt;p>On your local machine, generate a key pair with no passphrase:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>ssh-keygen -t ed25519 -C &lt;span style="color:#e6db74">&amp;#34;github-actions-deploy&amp;#34;&lt;/span> -f ~/.ssh/deploy_key -N &lt;span style="color:#e6db74">&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Add the &lt;strong>public key&lt;/strong> to Namecheap:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># In cPanel Terminal on Namecheap:&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo &lt;span style="color:#e6db74">&amp;#34;ssh-ed25519 AAAA...your-key-here github-actions-deploy&amp;#34;&lt;/span> &amp;gt;&amp;gt; ~/.ssh/authorized_keys
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="add-secrets-to-github">Add Secrets to GitHub&lt;/h3>
&lt;p>Go to your repo → &lt;strong>Settings&lt;/strong> → &lt;strong>Secrets and variables&lt;/strong> → &lt;strong>Actions&lt;/strong> and add:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Secret&lt;/th>
&lt;th>Value&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>NC_HOST&lt;/code>&lt;/td>
&lt;td>&lt;code>augmentedresilience.com&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>NC_USER&lt;/code>&lt;/td>
&lt;td>Your cPanel username&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>NC_PORT&lt;/code>&lt;/td>
&lt;td>Your SSH port (check cPanel)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>NC_SSH_KEY&lt;/code>&lt;/td>
&lt;td>The full private key (including BEGIN/END lines)&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="create-the-workflow">Create the Workflow&lt;/h3>
&lt;p>Add &lt;code>.github/workflows/deploy.yml&lt;/code> to your repo:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">Deploy to Namecheap&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">on&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">push&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">branches&lt;/span>: [&lt;span style="color:#ae81ff">main]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">jobs&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">deploy&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">runs-on&lt;/span>: &lt;span style="color:#ae81ff">ubuntu-latest&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">steps&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">Deploy via SSH&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">uses&lt;/span>: &lt;span style="color:#ae81ff">appleboy/ssh-action@v1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">with&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">host&lt;/span>: &lt;span style="color:#ae81ff">${{ secrets.NC_HOST }}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">username&lt;/span>: &lt;span style="color:#ae81ff">${{ secrets.NC_USER }}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">key&lt;/span>: &lt;span style="color:#ae81ff">${{ secrets.NC_SSH_KEY }}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">port&lt;/span>: &lt;span style="color:#ae81ff">${{ secrets.NC_PORT }}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">script&lt;/span>: |&lt;span style="color:#e6db74">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> cd ~/your-repo &amp;amp;&amp;amp; git pull origin main &amp;amp;&amp;amp; /bin/cp -R public/* ~/yourdomain.com/&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now every push to &lt;code>main&lt;/code> automatically deploys to your live site.&lt;/p>
&lt;h2 id="step-7-one-command-deploy-script">Step 7: One-Command Deploy Script&lt;/h2>
&lt;p>Five manual commands every time you publish? That&amp;rsquo;s not a workflow — that&amp;rsquo;s a chore. I had Claude write a Python script that handles everything in one shot:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-python" data-lang="python">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#!/usr/bin/env python3&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">&amp;#34;&amp;#34;&amp;#34;One-command deploy: Obsidian → Hugo → GitHub → Live site.&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> subprocess
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> sys
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">from&lt;/span> datetime &lt;span style="color:#f92672">import&lt;/span> datetime
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>PROJECT_DIR &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;~/Documents/Augmented-Resilience&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>OBSIDIAN_POSTS &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;~/projects/obsidian-vault/30-projects/augmented-resilience-posts&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>HUGO_POSTS &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">f&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">{&lt;/span>PROJECT_DIR&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">/content/posts&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">def&lt;/span> &lt;span style="color:#a6e22e">run&lt;/span>(cmd, description, cwd&lt;span style="color:#f92672">=&lt;/span>PROJECT_DIR):
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;&amp;#34;&amp;#34;Run a command and print status.&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> print(&lt;span style="color:#e6db74">f&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#ae81ff">\n&lt;/span>&lt;span style="color:#e6db74">{&lt;/span>&lt;span style="color:#e6db74">&amp;#39;=&amp;#39;&lt;/span>&lt;span style="color:#f92672">*&lt;/span>&lt;span style="color:#ae81ff">50&lt;/span>&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> print(&lt;span style="color:#e6db74">f&lt;/span>&lt;span style="color:#e6db74">&amp;#34; &lt;/span>&lt;span style="color:#e6db74">{&lt;/span>description&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> print(&lt;span style="color:#e6db74">f&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">{&lt;/span>&lt;span style="color:#e6db74">&amp;#39;=&amp;#39;&lt;/span>&lt;span style="color:#f92672">*&lt;/span>&lt;span style="color:#ae81ff">50&lt;/span>&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> result &lt;span style="color:#f92672">=&lt;/span> subprocess&lt;span style="color:#f92672">.&lt;/span>run(cmd, shell&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#66d9ef">True&lt;/span>, cwd&lt;span style="color:#f92672">=&lt;/span>cwd)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> result&lt;span style="color:#f92672">.&lt;/span>returncode &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> print(&lt;span style="color:#e6db74">f&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#ae81ff">\n&lt;/span>&lt;span style="color:#e6db74"> FAILED: &lt;/span>&lt;span style="color:#e6db74">{&lt;/span>description&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> sys&lt;span style="color:#f92672">.&lt;/span>exit(&lt;span style="color:#ae81ff">1&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> result
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">def&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>():
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> msg &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34; &amp;#34;&lt;/span>&lt;span style="color:#f92672">.&lt;/span>join(sys&lt;span style="color:#f92672">.&lt;/span>argv[&lt;span style="color:#ae81ff">1&lt;/span>:]) &lt;span style="color:#66d9ef">if&lt;/span> len(sys&lt;span style="color:#f92672">.&lt;/span>argv) &lt;span style="color:#f92672">&amp;gt;&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span> &lt;span style="color:#66d9ef">else&lt;/span> &lt;span style="color:#e6db74">f&lt;/span>&lt;span style="color:#e6db74">&amp;#34;Site update &lt;/span>&lt;span style="color:#e6db74">{&lt;/span>datetime&lt;span style="color:#f92672">.&lt;/span>now()&lt;span style="color:#f92672">.&lt;/span>strftime(&lt;span style="color:#e6db74">&amp;#39;%Y-%m-&lt;/span>&lt;span style="color:#e6db74">%d&lt;/span>&lt;span style="color:#e6db74"> %H:%M&amp;#39;&lt;/span>)&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> run(&lt;span style="color:#e6db74">f&lt;/span>&lt;span style="color:#e6db74">&amp;#39;rsync -av --delete &amp;#34;&lt;/span>&lt;span style="color:#e6db74">{&lt;/span>OBSIDIAN_POSTS&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34; &amp;#34;&lt;/span>&lt;span style="color:#e6db74">{&lt;/span>HUGO_POSTS&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&amp;#39;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;Syncing posts from Obsidian&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> run(&lt;span style="color:#e6db74">f&lt;/span>&lt;span style="color:#e6db74">&amp;#34;python3 &lt;/span>&lt;span style="color:#e6db74">{&lt;/span>PROJECT_DIR&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">/images.py&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;Processing images&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> run(&lt;span style="color:#e6db74">&amp;#34;hugo&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;Building site with Hugo&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> run(&lt;span style="color:#e6db74">&amp;#34;git add .&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;Staging changes&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> result &lt;span style="color:#f92672">=&lt;/span> subprocess&lt;span style="color:#f92672">.&lt;/span>run(&lt;span style="color:#e6db74">&amp;#34;git diff --cached --quiet&amp;#34;&lt;/span>, shell&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#66d9ef">True&lt;/span>, cwd&lt;span style="color:#f92672">=&lt;/span>PROJECT_DIR)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> result&lt;span style="color:#f92672">.&lt;/span>returncode &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> print(&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#ae81ff">\n&lt;/span>&lt;span style="color:#e6db74"> No changes to commit. Site is up to date.&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> run(&lt;span style="color:#e6db74">f&lt;/span>&lt;span style="color:#e6db74">&amp;#39;git commit -m &amp;#34;&lt;/span>&lt;span style="color:#e6db74">{&lt;/span>msg&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&amp;#39;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;Committing&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> run(&lt;span style="color:#e6db74">&amp;#34;git push origin main&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;Pushing to GitHub&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> print(&lt;span style="color:#e6db74">f&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#ae81ff">\n&lt;/span>&lt;span style="color:#e6db74">{&lt;/span>&lt;span style="color:#e6db74">&amp;#39;=&amp;#39;&lt;/span>&lt;span style="color:#f92672">*&lt;/span>&lt;span style="color:#ae81ff">50&lt;/span>&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> print(&lt;span style="color:#e6db74">&amp;#34; DEPLOYED! Your site will be live shortly.&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> print(&lt;span style="color:#e6db74">f&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">{&lt;/span>&lt;span style="color:#e6db74">&amp;#39;=&amp;#39;&lt;/span>&lt;span style="color:#f92672">*&lt;/span>&lt;span style="color:#ae81ff">50&lt;/span>&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#ae81ff">\n&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">if&lt;/span> __name__ &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#e6db74">&amp;#34;__main__&amp;#34;&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> main()
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Save this as &lt;code>deploy.py&lt;/code> in your project root. Now the entire workflow is:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Default timestamped commit message&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>python3 deploy.py
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Or with a custom message&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>python3 deploy.py &lt;span style="color:#e6db74">&amp;#34;Add new blog post about deployment&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The script runs every step in sequence — syncs from Obsidian, converts image links, builds with Hugo, commits, and pushes. If any step fails, it stops immediately so you don&amp;rsquo;t push a broken build. Combined with the GitHub Actions workflow from Step 6, pushing triggers the auto-deploy to Namecheap. One command, fully live.&lt;/p>
&lt;h2 id="lessons-learned">Lessons Learned&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>SSH passphrases break cPanel automation.&lt;/strong> Always remove the passphrase from keys used by cPanel&amp;rsquo;s Git Version Control.&lt;/li>
&lt;li>&lt;strong>Theme names must match directory names.&lt;/strong> Hugo looks for the theme in &lt;code>themes/&amp;lt;theme-name&amp;gt;/&lt;/code>, so the &lt;code>theme&lt;/code> value in your config must match exactly.&lt;/li>
&lt;li>&lt;strong>Don&amp;rsquo;t clone into the live site directory.&lt;/strong> Clone to a separate folder and use &lt;code>.cpanel.yml&lt;/code> to copy the built files over.&lt;/li>
&lt;li>&lt;strong>GitHub Actions + SSH is the cleanest auto-deploy for shared hosting.&lt;/strong> No webhooks, no cron jobs — just a simple SSH action that runs on every push.&lt;/li>
&lt;li>&lt;strong>Claude Code with PAI made this possible in a single session.&lt;/strong> From debugging build errors to SSH key troubleshooting to writing GitHub Actions workflows, having an AI pair programmer turned what could have been hours of Stack Overflow rabbit holes into a smooth, guided process.&lt;/li>
&lt;/ul>
&lt;h2 id="tools-used">Tools Used&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://gohugo.io/" target="_blank" rel="noopener noreferrer">Hugo&lt;/a>
— Static site generator&lt;/li>
&lt;li>&lt;a href="https://github.com/mirus-ua/hugo-theme-re-terminal" target="_blank" rel="noopener noreferrer">re-terminal theme&lt;/a>
— Hugo theme&lt;/li>
&lt;li>&lt;a href="https://www.namecheap.com/" target="_blank" rel="noopener noreferrer">Namecheap&lt;/a>
— Shared hosting with cPanel&lt;/li>
&lt;li>&lt;a href="https://github.com/features/actions" target="_blank" rel="noopener noreferrer">GitHub Actions&lt;/a>
— CI/CD automation&lt;/li>
&lt;li>&lt;a href="https://claude.ai/" target="_blank" rel="noopener noreferrer">Claude Code&lt;/a>
— AI pair programmer&lt;/li>
&lt;li>&lt;a href="https://danielmiessler.com/blog/personal-ai-infrastructure" target="_blank" rel="noopener noreferrer">Personal AI Infrastructure (PAI)&lt;/a>
— Workflow engine&lt;/li>
&lt;li>&lt;a href="https://obsidian.md/" target="_blank" rel="noopener noreferrer">Obsidian&lt;/a>
— Content authoring&lt;/li>
&lt;li>&lt;a href="https://code.visualstudio.com/" target="_blank" rel="noopener noreferrer">VS Code&lt;/a>
- Development environment; used as the workspace for Claude Code sessions&lt;/li>
&lt;/ul>
&lt;h2 id="resources">Resources&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://youtu.be/dnE7c0ELEH8?si=YEDoaoiekMYJIe3U" target="_blank" rel="noopener noreferrer">I started a blog&amp;hellip;..in 2024 (why you should too)&lt;/a>
— The YouTube video that inspired me to start this blog&lt;/li>
&lt;li>&lt;a href="https://danielmiessler.com/blog/personal-ai-infrastructure" target="_blank" rel="noopener noreferrer">Building a Personal AI Infrastructure (PAI)&lt;/a>
— Daniel Miessler&amp;rsquo;s guide to building your own Personal AI system&lt;/li>
&lt;/ul></content></item></channel></rss>