<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <author>
    <name>MarchSnow</name>
  </author>
  <generator uri="https://hexo.io/">Hexo</generator>
  <id>https://blog.88889000.xyz/</id>
  <link href="https://blog.88889000.xyz/" rel="alternate"/>
  <link href="https://blog.88889000.xyz/atom.xml" rel="self"/>
  <rights>All rights reserved 2026, MarchSnow</rights>
  <subtitle>
    <![CDATA[Tech Insights & Development Journey]]>
  </subtitle>
  <title>MarchSnow's Blog</title>
  <updated>2026-05-26T08:44:02.242Z</updated>
  <entry>
    <author>
      <name>MarchSnow</name>
    </author>
    <category term="Tech" scheme="https://blog.88889000.xyz/categories/Tech/"/>
    <category term="Git" scheme="https://blog.88889000.xyz/tags/Git/"/>
    <category term="GitHub" scheme="https://blog.88889000.xyz/tags/GitHub/"/>
    <category term="Privacy" scheme="https://blog.88889000.xyz/tags/Privacy/"/>
    <content>
      <![CDATA[<h2 id="Introduction"><a href="#Introduction" class="headerlink" title="Introduction"></a>Introduction</h2><p>Git commits require configuring a <code>user.email</code> field, and most users set it to their GitHub registered email to enable commit attribution verification</p><p>However, most people don’t realize that this seemingly innocuous configuration actually exposes their personal email address in plain text within public repositories</p><p>Anyone can retrieve your real email address with zero barrier, exposing you to various privacy risks</p><h2 id="Git-Commit-Metadata-and-Email-Association"><a href="#Git-Commit-Metadata-and-Email-Association" class="headerlink" title="Git Commit Metadata and Email Association"></a>Git Commit Metadata and Email Association</h2><p>When using Git for version control, you must configure a committer identity:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ git config --global user.name <span class="string">&quot;GithubUserName&quot;</span></span><br><span class="line">$ git config --global user.email <span class="string">&quot;YourEmail@mail.example.com&quot;</span></span><br></pre></td></tr></table></figure><h3 id="How-GitHub-Commit-Attribution-Works"><a href="#How-GitHub-Commit-Attribution-Works" class="headerlink" title="How GitHub Commit Attribution Works"></a>How GitHub Commit Attribution Works</h3><p>GitHub’s commit attribution mechanism validates against the <code>user.email</code> field in your Git configuration. The core logic is:</p><ul><li><strong>Email as the primary key</strong>: GitHub only uses the email address in commit metadata to identify the committer and associate the commit with the corresponding account</li><li><strong>Username is cosmetic</strong>: The <code>user.name</code> configured in Git is only used for display and does not participate in any validation logic</li></ul><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># In other words, whatever you put here doesn&#x27;t affect commit attribution (as long as your email is correctly set)</span></span><br><span class="line">$ git config --global user.name <span class="string">&quot;AnyDisplayName&quot;</span></span><br></pre></td></tr></table></figure><h2 id="What-Does-Commit-Metadata-Expose"><a href="#What-Does-Commit-Metadata-Expose" class="headerlink" title="What Does Commit Metadata Expose?"></a>What Does Commit Metadata Expose?</h2><h3 id="Commit-Metadata-at-Your-Fingertips"><a href="#Commit-Metadata-at-Your-Fingertips" class="headerlink" title="Commit Metadata at Your Fingertips"></a>Commit Metadata at Your Fingertips</h3><p>While the GitHub Web UI doesn’t directly display the committer’s email, it can be easily retrieved by inspecting the metadata:</p><p><strong>Accessing any Commit</strong>:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://github.com/&#123;owner&#125;/&#123;repo&#125;/commit/&#123;commit-sha&#125;</span><br></pre></td></tr></table></figure><p><strong>Viewing Commit Metadata</strong>:<br>Append <code>.patch</code> to the commit URL:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://github.com/&#123;owner&#125;/&#123;repo&#125;/commit/&#123;commit-sha&#125;.patch</span><br></pre></td></tr></table></figure><p>The resulting URL returns plain text in Git patch format, containing the full commit metadata:</p><figure class="highlight diff"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">From &#123;commit-sha&#125; Mon Sep 17 00:00:00 2001</span><br><span class="line">From: &#123;user.name&#125; &lt;&#123;user.email&#125;&gt;</span><br><span class="line">Date: Sun, 8 Mar 2026 12:00:00 +0000</span><br><span class="line">Subject: [PATCH] &#123;commit-message&#125;</span><br></pre></td></tr></table></figure><p><strong>What information is leaked?</strong>:</p><ul><li>Line 1: Commit SHA-1 hash</li><li>Line 2: <strong>Plain text exposure of committer’s email address (PII data)</strong></li><li>Line 3: Commit timestamp</li><li>Line 4: Commit message</li></ul><p>This means that in all public repository commits, any personal email address configured in Git by the committer can be effortlessly obtained by any third party with zero barrier</p><h2 id="Privacy-Protection-Make-Good-Use-of-GitHub-No-Reply-Email"><a href="#Privacy-Protection-Make-Good-Use-of-GitHub-No-Reply-Email" class="headerlink" title="Privacy Protection: Make Good Use of GitHub No-Reply Email"></a>Privacy Protection: Make Good Use of GitHub No-Reply Email</h2><p>GitHub No-Reply email is a great feature — it’s free for the taking</p><h3 id="How-It-Works-Legacy-Format"><a href="#How-It-Works-Legacy-Format" class="headerlink" title="How It Works (Legacy Format)"></a>How It Works (Legacy Format)</h3><p>Configure the no-reply email address provided by GitHub as your Git committer email:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ git config --global user.email <span class="string">&quot;&#123;username&#125;@users.noreply.github.com&quot;</span></span><br></pre></td></tr></table></figure><p><strong>Core logic</strong>:</p><ul><li>GitHub recognizes this email as a No-Reply format</li><li>GitHub automatically maps the {username} prefix to the corresponding GitHub account</li><li>This protects your privacy while maintaining normal commit functionality</li></ul><h3 id="Limitations"><a href="#Limitations" class="headerlink" title="Limitations?"></a>Limitations?</h3><p>What’s described above is the <strong>legacy version</strong> of the No-Reply email, which has the following limitation:</p><p>This email format is tightly coupled with your GitHub username. If you change your username, you will lose all commit history associated with <code>&lt;{originalusername}@users.noreply.github.com&gt;</code></p><p>If you need a more aggressive privacy protection strategy<span class="spoiler">(change your username and disappear)</span> then… <span class="spoiler">this might actually be a nice side effect XD</span></p><h2 id="Can’t-Have-It-Both-Ways-Here’s-Another-Workaround"><a href="#Can’t-Have-It-Both-Ways-Here’s-Another-Workaround" class="headerlink" title="Can’t Have It Both Ways? Here’s Another Workaround"></a>Can’t Have It Both Ways? Here’s Another Workaround</h2><h3 id="The-New-No-Reply-Email"><a href="#The-New-No-Reply-Email" class="headerlink" title="The New No-Reply Email"></a>The New No-Reply Email</h3><p>GitHub provides a persistent no-reply email based on your User ID:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;user-id&#125;+&#123;username&#125;@users.noreply.github.com</span><br></pre></td></tr></table></figure><p>The numeric prefix is your GitHub account’s internal User ID, which is unique</p><p>With the new No-Reply email, you can change your username freely without breaking your historical commit records</p><p>This means all commits using this email will remain associated with this User ID’s account</p><h3 id="How-to-Get-the-New-No-Reply-Email"><a href="#How-to-Get-the-New-No-Reply-Email" class="headerlink" title="How to Get the New No-Reply Email"></a>How to Get the New No-Reply Email</h3><p><strong>Step 1</strong>: Open GitHub Settings - Emails</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://github.com/settings/emails</span><br></pre></td></tr></table></figure><p><strong>Step 2</strong>: Enable Privacy Protection</p><ul><li>Enable the <code>Keep my email addresses private</code> option</li></ul><p><strong>Step 3</strong>: Confirm Changes</p><ul><li><p>Follow the prompts to complete the two-step confirmation process</p></li><li><p>The system will display your assigned ID-based no-reply email</p></li></ul><p><strong>Step 4</strong>: Retrieve the Email Address</p><p>After enabling it, the Emails page will show:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">We&#x27;ll remove your public profile email and use &#123;user-id&#125;+&#123;username&#125;@users.noreply.github.com </span><br><span class="line">when performing web-based Git operations (e.g. edits and merges) and sending email on your behalf.</span><br></pre></td></tr></table></figure><p><strong>Step 5</strong>: Update Your Local Git Configuration</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ git config --global user.email <span class="string">&quot;&#123;user-id&#125;+&#123;username&#125;@users.noreply.github.com&quot;</span></span><br></pre></td></tr></table></figure><h2 id="Summary"><a href="#Summary" class="headerlink" title="Summary"></a>Summary</h2><p>GitHub No-Reply email is a lightweight yet effective privacy protection mechanism</p><p>By replacing your Git commit email with an ID-based no-reply address, you can effectively prevent your personal email from being exposed without affecting code collaboration</p><p>This is a basic security configuration that every GitHub user concerned about privacy should enable</p>]]>
    </content>
    <id>https://blog.88889000.xyz/2026/tech/github-noreply-email-privacy-protection/</id>
    <link href="https://blog.88889000.xyz/2026/tech/github-noreply-email-privacy-protection/"/>
    <published>2026-03-07T18:31:57.000Z</published>
    <summary>Leveraging GitHub's No-Reply email mechanism to protect your privacy when committing with Git</summary>
    <title>Using GitHub No-Reply Email for an Extra Layer of Privacy Protection</title>
    <updated>2026-05-26T08:44:02.242Z</updated>
  </entry>
  <entry>
    <author>
      <name>MarchSnow</name>
    </author>
    <category term="Tech" scheme="https://blog.88889000.xyz/categories/Tech/"/>
    <category term="Hexo" scheme="https://blog.88889000.xyz/tags/Hexo/"/>
    <category term="Github" scheme="https://blog.88889000.xyz/tags/Github/"/>
    <category term="GitHub Pages" scheme="https://blog.88889000.xyz/tags/GitHub-Pages/"/>
    <category term="GitHub Actions" scheme="https://blog.88889000.xyz/tags/GitHub-Actions/"/>
    <content>
      <![CDATA[<h2 id="Preface"><a href="#Preface" class="headerlink" title="Preface"></a>Preface</h2><h3 id="What-is-GitHub-Pages"><a href="#What-is-GitHub-Pages" class="headerlink" title="What is GitHub Pages?"></a>What is GitHub Pages?</h3><p>GitHub Pages is a free static website hosting service provided by GitHub<br>You just need to push your website files to a GitHub repository, and your site will be accessible via a domain like <code>username.github.io</code><br>It supports custom domains and doesn’t require purchasing a server, making it ideal for personal blogs, project documentation, and other static websites</p><h3 id="What-is-Hexo"><a href="#What-is-Hexo" class="headerlink" title="What is Hexo?"></a>What is Hexo?</h3><p>Hexo is a fast, simple, and powerful blogging framework<br>It is built on Node.js, parses articles using Markdown, and can generate static web pages in seconds<br>Hexo also boasts a rich ecosystem of themes and plugins, allowing you to easily create a personalized blog</p><h3 id="How-It-Works"><a href="#How-It-Works" class="headerlink" title="How It Works"></a>How It Works</h3><p>The approach used in this tutorial is:</p><ol><li>Use a <strong>private repository</strong> to store Hexo source files (Markdown articles, configuration files, etc.)</li><li>Use a <strong>public repository</strong> to host the generated static website files</li><li>Use <strong>GitHub Actions</strong> to automate building and deployment</li></ol><p>When you push updates to your private repository, GitHub Actions will automatically:</p><ul><li>Set up the Hexo environment</li><li>Generate static web pages based on your configuration</li><li>Push the generated files to the public repository</li><li>GitHub Pages detects the file changes and automatically updates your blog</li></ul><h3 id="Can-I-Use-a-Custom-Domain"><a href="#Can-I-Use-a-Custom-Domain" class="headerlink" title="Can I Use a Custom Domain?"></a>Can I Use a Custom Domain?</h3><p>Sure, once configured, you can bind your own domain in GitHub Pages settings</p><h3 id="Prerequisites"><a href="#Prerequisites" class="headerlink" title="Prerequisites"></a>Prerequisites</h3><p>Before you begin, make sure you have:</p><ul><li>✅ A GitHub account</li><li>✅ Node.js environment (recommended: the latest v22 LTS version)</li><li>✅ A code editor (VS Code recommended)</li><li>✅ Git installed (for committing code to GitHub repositories)</li></ul><blockquote><p><strong>Notes</strong></p><ul><li>All references to “GitHub username” in this article refer to the <code>username</code> you use to log in to GitHub, not your display name</li><li>It is recommended to keep English comments in configuration files, as they help you understand the meaning of each option</li></ul></blockquote><hr><h2 id="Step-1-Local-Installation-and-Initialization"><a href="#Step-1-Local-Installation-and-Initialization" class="headerlink" title="Step 1: Local Installation and Initialization"></a>Step 1: Local Installation and Initialization</h2><h3 id="1-1-Install-Node-js"><a href="#1-1-Install-Node-js" class="headerlink" title="1.1 Install Node.js"></a>1.1 Install Node.js</h3><p>Visit the <a href="https://nodejs.org/">Node.js official website</a> to download and install the latest LTS version (I am using v22.14.0)</p><p>After installation, verify in your terminal:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">node -v   <span class="comment"># Should display v22.14.0 or similar</span></span><br><span class="line">npm -v    <span class="comment"># Should display the npm version</span></span><br></pre></td></tr></table></figure><h3 id="1-2-Create-a-Project-Folder"><a href="#1-2-Create-a-Project-Folder" class="headerlink" title="1.2 Create a Project Folder"></a>1.2 Create a Project Folder</h3><p>Create a folder (it’s best to avoid Chinese characters in the path to prevent mysterious bugs) in your preferred location, for example <code>Blog</code><br>Then open it with VS Code</p><h3 id="1-3-Install-Hexo-CLI"><a href="#1-3-Install-Hexo-CLI" class="headerlink" title="1.3 Install Hexo CLI"></a>1.3 Install Hexo CLI</h3><p>Run the following in the VS Code terminal:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install -g hexo-cli</span><br></pre></td></tr></table></figure><p>Verify the installation:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hexo version</span><br></pre></td></tr></table></figure><h3 id="1-4-Initialize-the-Hexo-Project"><a href="#1-4-Initialize-the-Hexo-Project" class="headerlink" title="1.4 Initialize the Hexo Project"></a>1.4 Initialize the Hexo Project</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">hexo init</span><br><span class="line">npm install</span><br></pre></td></tr></table></figure><p>After initialization, your project directory structure should look like this:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">Blog/</span><br><span class="line">├── _config.yml       # Site configuration file</span><br><span class="line">├── source/           # Source folder</span><br><span class="line">│   └── _posts/       # Markdown articles go here</span><br><span class="line">├── themes/           # Themes folder</span><br><span class="line">└── xxxx             # Other folders/files, not listed here</span><br></pre></td></tr></table></figure><h3 id="1-5-Configure-Site-URL"><a href="#1-5-Configure-Site-URL" class="headerlink" title="1.5 Configure Site URL"></a>1.5 Configure Site URL</h3><p>Edit the <code>_config.yml</code> file in the root directory, find the <code># URL</code> section:</p><p><strong>If using the default GitHub Pages domain:</strong></p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># URL</span></span><br><span class="line"><span class="comment">## Set your site url here. For example, if you use GitHub Page, set url as &#x27;https://username.github.io/project&#x27;</span></span><br><span class="line"><span class="attr">url:</span> <span class="string">https://&lt;YourGitHubUsername&gt;.github.io/</span></span><br></pre></td></tr></table></figure><p>Replace <code>&lt;YourGitHubUsername&gt;</code> with your actual username, e.g., <code>https://gebilaowang.github.io/</code></p><p><strong>If using a custom domain:</strong></p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># URL</span></span><br><span class="line"><span class="comment">## Set your site url here. For example, if you use GitHub Page, set url as &#x27;https://username.github.io/project&#x27;</span></span><br><span class="line"><span class="attr">url:</span> <span class="string">https://your-domain.com/</span></span><br></pre></td></tr></table></figure><h3 id="1-6-Local-Preview"><a href="#1-6-Local-Preview" class="headerlink" title="1.6 Local Preview"></a>1.6 Local Preview</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hexo s <span class="comment"># &quot;s&quot; is short for &quot;server&quot;</span></span><br></pre></td></tr></table></figure><p>The terminal should display:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">INFO  Validating config</span><br><span class="line">INFO  Start processing</span><br><span class="line">INFO  Hexo is running at http://localhost:4000/ . Press Ctrl+C to stop.</span><br></pre></td></tr></table></figure><p>Open <code>http://localhost:4000/</code> in your browser, and you should see the Hexo page</p><hr><h2 id="Step-2-Theme-Configuration-Optional"><a href="#Step-2-Theme-Configuration-Optional" class="headerlink" title="Step 2: Theme Configuration (Optional)"></a>Step 2: Theme Configuration (Optional)</h2><p>The default Hexo theme is quite minimal. If you want a more polished look, you can install a third-party theme.</p><h3 id="Popular-Theme-Recommendations"><a href="#Popular-Theme-Recommendations" class="headerlink" title="Popular Theme Recommendations"></a>Popular Theme Recommendations</h3><ul><li><strong><a href="https://github.com/next-theme/hexo-theme-next">NexT</a></strong> - Minimalist style</li><li><strong><a href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></strong> - Beautiful interface, responsive design</li><li><strong><a href="https://github.com/fluid-dev/hexo-theme-fluid">Fluid</a></strong> - Material Design style</li><li><strong><a href="https://github.com/blinkfox/hexo-theme-matery">Matery</a></strong> - Card-based design</li></ul><p>Each theme comes with detailed configuration documentation. Please refer to the README.md of the corresponding GitHub repository for setup instructions</p><hr><h2 id="Step-3-Create-GitHub-Repositories"><a href="#Step-3-Create-GitHub-Repositories" class="headerlink" title="Step 3: Create GitHub Repositories"></a>Step 3: Create GitHub Repositories</h2><h3 id="3-1-Create-a-Private-Repository-for-Source-Files"><a href="#3-1-Create-a-Private-Repository-for-Source-Files" class="headerlink" title="3.1 Create a Private Repository (for Source Files)"></a>3.1 Create a Private Repository (for Source Files)</h3><ol><li>Log in to GitHub, click the <code>+</code> in the top right corner → <code>New repository</code></li><li>Choose any repository name, e.g., <code>hexo-blog</code> or <code>blog-source</code></li><li><strong>Important:</strong> Select <code>Private</code></li><li>Do not initialize with a README, .gitignore, or license</li><li>Click <code>Create repository</code></li></ol><h3 id="3-2-Create-a-Public-Repository-for-Hosting-the-Site"><a href="#3-2-Create-a-Public-Repository-for-Hosting-the-Site" class="headerlink" title="3.2 Create a Public Repository (for Hosting the Site)"></a>3.2 Create a Public Repository (for Hosting the Site)</h3><ol><li>Click <code>+</code> again → <code>New repository</code></li><li><strong>Important:</strong> The repository name must strictly follow the format <code>&lt;YourGitHubUsername&gt;.github.io</code><ul><li>For example, if your username is <code>gebilaowang</code>, the repository name should be <code>gebilaowang.github.io</code></li><li>The name must match your username exactly, including capitalization</li></ul></li><li>Select <code>Public</code></li><li>Click <code>Create repository</code></li></ol><blockquote><p><strong>Why create two repositories?</strong></p><ul><li>The private repository protects your source files (configurations, drafts, etc.) from public exposure</li><li>The public repository only contains the generated static files, meeting GitHub Pages requirements</li><li>Separating source code from build artifacts makes maintenance easier</li></ul></blockquote><hr><h2 id="Step-4-Configure-GitHub-Actions-for-Automated-Deployment"><a href="#Step-4-Configure-GitHub-Actions-for-Automated-Deployment" class="headerlink" title="Step 4: Configure GitHub Actions for Automated Deployment"></a>Step 4: Configure GitHub Actions for Automated Deployment</h2><h3 id="4-1-Create-a-Workflow-File"><a href="#4-1-Create-a-Workflow-File" class="headerlink" title="4.1 Create a Workflow File"></a>4.1 Create a Workflow File</h3><p>Navigate to the <code>.github/workflows/</code> folder in your project root (create it if it doesn’t exist):</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">mkdir</span> -p .github/workflows</span><br></pre></td></tr></table></figure><p>Create a <code>deploy.yml</code> file inside <code>.github/workflows/</code> with the following content:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">name:</span> <span class="string">Deploy</span> <span class="string">to</span> <span class="string">GitHub</span> <span class="string">Pages</span></span><br><span class="line"></span><br><span class="line"><span class="attr">on:</span></span><br><span class="line">  <span class="attr">push:</span></span><br><span class="line">    <span class="attr">branches:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">main</span>  <span class="comment"># Triggers when pushing to the main branch</span></span><br><span class="line"></span><br><span class="line"><span class="attr">jobs:</span></span><br><span class="line">  <span class="attr">deploy-gh-pages:</span></span><br><span class="line">    <span class="attr">runs-on:</span> <span class="string">ubuntu-latest</span></span><br><span class="line">    <span class="attr">steps:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Checkout</span></span><br><span class="line">        <span class="attr">uses:</span> <span class="string">actions/checkout@master</span></span><br><span class="line"></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Build</span> <span class="string">and</span> <span class="string">Deploy</span></span><br><span class="line">        <span class="attr">uses:</span> <span class="string">theme-keep/hexo-deploy-github-pages-action@master</span></span><br><span class="line">        <span class="attr">env:</span></span><br><span class="line">          <span class="attr">BRANCH:</span> <span class="string">main</span></span><br><span class="line">          <span class="attr">PUBLISH_DIR:</span> <span class="string">./public</span></span><br><span class="line">          <span class="attr">PERSONAL_TOKEN:</span> <span class="string">$&#123;&#123;</span> <span class="string">secrets.HEXO_GHPAGE_SECRET</span> <span class="string">&#125;&#125;</span></span><br><span class="line">          <span class="attr">PUBLISH_REPOSITORY:</span> <span class="string">&lt;YourGitHubUsername&gt;/&lt;YourGitHubUsername&gt;.github.io</span></span><br></pre></td></tr></table></figure><p><strong>Things you must change:</strong></p><ul><li>Replace <code>&lt;YourGitHubUsername&gt;</code> in the last line with your actual username</li><li>For example: <code>PUBLISH_REPOSITORY: gebilaowang/gebilaowang.github.io</code></li></ul><h3 id="4-2-Generate-a-GitHub-Personal-Access-Token"><a href="#4-2-Generate-a-GitHub-Personal-Access-Token" class="headerlink" title="4.2 Generate a GitHub Personal Access Token"></a>4.2 Generate a GitHub Personal Access Token</h3><ol><li>Click your profile picture in the top right corner of GitHub → <code>Settings</code></li><li>Scroll to the bottom of the left sidebar, click <code>Developer settings</code></li><li>Expand <code>Personal access tokens</code> → Click <code>Tokens (classic)</code></li><li>Click <code>Generate new token</code> in the top right → Select <code>Generate new token (classic)</code></li></ol><p><strong>Configure the Token:</strong></p><ul><li><strong>Note:</strong> Add a description, e.g., <code>Hexo Deployment Token</code></li><li><strong>Expiration:</strong> Select <code>No expiration</code></li><li><strong>Permissions:</strong><ul><li>✅ <code>repo</code> (Full control of private repositories)</li><li>✅ <code>workflow</code> (Update GitHub Action workflows)</li></ul></li></ul><ol start="5"><li>Scroll to the bottom and click <code>Generate token</code></li><li><strong>Important:</strong> Copy the generated token immediately (format: <code>ghp_xxxxxxxxxxxx</code>)</li></ol><blockquote><p>⚠️ <strong>Warning:</strong><br>The token is only shown once! Save it immediately in a secure location; if lost, you will need to regenerate it<br>Do not share this token, as a leaked token could lead to your GitHub account being compromised!</p></blockquote><h3 id="4-3-Configure-Repository-Secret"><a href="#4-3-Configure-Repository-Secret" class="headerlink" title="4.3 Configure Repository Secret"></a>4.3 Configure Repository Secret</h3><ol><li>Open your <strong>private repository</strong> (the one storing source files)</li><li>Go to <code>Settings</code> → <code>Secrets and variables</code> → <code>Actions</code></li><li>Click <code>New repository secret</code></li><li>Fill in:<ul><li><strong>Name:</strong> <code>HEXO_GHPAGE_SECRET</code> (if you changed the variable name in deploy.yml, make sure they match)</li><li><strong>Secret:</strong> Paste the token you just copied</li></ul></li><li>Click <code>Add secret</code></li></ol><hr><h2 id="Step-5-Push-Code-and-Deploy"><a href="#Step-5-Push-Code-and-Deploy" class="headerlink" title="Step 5: Push Code and Deploy"></a>Step 5: Push Code and Deploy</h2><h3 id="5-1-Initialize-a-Git-Repository"><a href="#5-1-Initialize-a-Git-Repository" class="headerlink" title="5.1 Initialize a Git Repository"></a>5.1 Initialize a Git Repository</h3><p>If your VS Code terminal is still running <code>hexo server</code>, press <code>Ctrl+C</code> to stop it first</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">git init</span><br><span class="line">git add .</span><br><span class="line">git commit -m <span class="string">&quot;Initial commit: Hexo blog setup&quot;</span></span><br></pre></td></tr></table></figure><h3 id="5-2-Link-the-Remote-Repository"><a href="#5-2-Link-the-Remote-Repository" class="headerlink" title="5.2 Link the Remote Repository"></a>5.2 Link the Remote Repository</h3><p>Link your local repository to your private repository:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git remote add origin https://github.com/&lt;YourGitHubUsername&gt;/&lt;YourPrivateRepositoryName&gt;.git</span><br></pre></td></tr></table></figure><p>For example:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git remote add origin https://github.com/gebilaowang/hexo-blog.git</span><br></pre></td></tr></table></figure><h3 id="5-3-Push-to-GitHub"><a href="#5-3-Push-to-GitHub" class="headerlink" title="5.3 Push to GitHub"></a>5.3 Push to GitHub</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git branch -M main</span><br><span class="line">git push -u origin main</span><br></pre></td></tr></table></figure><h3 id="5-4-Check-Deployment-Progress"><a href="#5-4-Check-Deployment-Progress" class="headerlink" title="5.4 Check Deployment Progress"></a>5.4 Check Deployment Progress</h3><ol><li>After pushing, open your private repository</li><li>Click the <code>Actions</code> tab at the top</li><li>You should see a running workflow named <code>Deploy to GitHub Pages</code></li><li>Click into it to view detailed build logs</li><li>Wait for the green ✅ icon, which indicates a successful deployment</li></ol><h3 id="5-5-Configure-GitHub-Pages"><a href="#5-5-Configure-GitHub-Pages" class="headerlink" title="5.5 Configure GitHub Pages"></a>5.5 Configure GitHub Pages</h3><ol><li>Open your <strong>public repository</strong> (<code>username.github.io</code>)</li><li>By now, files should already be there (pushed automatically by Actions)</li><li>Go to <code>Settings</code> → <code>Pages</code></li><li>Under <strong>Build and deployment</strong>:<ul><li><strong>Source:</strong> Select <code>Deploy from a branch</code></li><li><strong>Branch:</strong> Select <code>main</code>, leave the directory as <code>/ (root)</code></li></ul></li><li>Click <code>Save</code></li></ol><h3 id="5-6-Visit-Your-Blog"><a href="#5-6-Visit-Your-Blog" class="headerlink" title="5.6 Visit Your Blog"></a>5.6 Visit Your Blog</h3><p>Wait 1-2 minutes, then open your browser and navigate to:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://&lt;YourGitHubUsername&gt;.github.io/</span><br></pre></td></tr></table></figure><p>If you see the Hexo interface, congratulations</p><p>Your Hexo blog has been successfully deployed to GitHub Pages</p><hr><h2 id="Step-6-Daily-Writing-Workflow"><a href="#Step-6-Daily-Writing-Workflow" class="headerlink" title="Step 6: Daily Writing Workflow"></a>Step 6: Daily Writing Workflow</h2><h3 id="6-1-Create-a-New-Article"><a href="#6-1-Create-a-New-Article" class="headerlink" title="6.1 Create a New Article"></a>6.1 Create a New Article</h3><p>Open the VS Code terminal and run:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hexo new <span class="string">&quot;Article Title&quot;</span></span><br></pre></td></tr></table></figure><p>This will generate a new Markdown file in the <code>source/_posts/</code> directory</p><h3 id="6-2-Edit-the-Article"><a href="#6-2-Edit-the-Article" class="headerlink" title="6.2 Edit the Article"></a>6.2 Edit the Article</h3><p>Open the newly generated Markdown file and start writing</p><p><strong>Example:</strong></p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">---</span><br><span class="line">title: My first blog</span><br><span class="line">date: 2025-03-06 12:00:00</span><br><span class="line">tags:</span><br><span class="line"><span class="bullet">  -</span> Essay</span><br><span class="line">categories:</span><br><span class="line"><span class="bullet">  -</span> Daily</span><br><span class="line"><span class="section">description: This is my first blog.</span></span><br><span class="line"><span class="section">---</span></span><br><span class="line"></span><br><span class="line">This is where the content goes...</span><br></pre></td></tr></table></figure><h3 id="6-3-Local-Preview"><a href="#6-3-Local-Preview" class="headerlink" title="6.3 Local Preview"></a>6.3 Local Preview</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">hexo clean  <span class="comment"># Clear cache</span></span><br><span class="line">hexo generate  <span class="comment"># or hexo g, generate static files</span></span><br><span class="line">hexo server  <span class="comment"># or hexo s, start local server</span></span><br></pre></td></tr></table></figure><p>Open <code>http://localhost:4000/</code> in your browser to preview</p><h3 id="6-4-Publish-Updates"><a href="#6-4-Publish-Updates" class="headerlink" title="6.4 Publish Updates"></a>6.4 Publish Updates</h3><p>Once everything looks good, commit and push to GitHub:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">git add .</span><br><span class="line">git commit -m <span class="string">&quot;docs: &lt;New Article Title&gt;&quot;</span> <span class="comment"># It&#x27;s recommended to note what was added in the commit message for easier management later</span></span><br><span class="line">git push</span><br></pre></td></tr></table></figure><p>After pushing, GitHub Actions will:</p><ol><li>Detect the new push and run the build process</li><li>Generate static files</li><li>Deploy to GitHub Pages</li></ol><p>Wait a moment, refresh your blog, and the new article will appear</p><hr><h2 id="FAQ"><a href="#FAQ" class="headerlink" title="FAQ"></a>FAQ</h2><h3 id="Q1-What-if-the-Actions-build-fails"><a href="#Q1-What-if-the-Actions-build-fails" class="headerlink" title="Q1: What if the Actions build fails?"></a>Q1: What if the Actions build fails?</h3><p><strong>Solution:</strong></p><ol><li>Check if <code>PUBLISH_REPOSITORY</code> in <code>deploy.yml</code> is correct</li><li>Confirm that the token has <code>repo</code> and <code>workflow</code> permissions enabled</li><li>Check the Actions logs, search for the error details on Google, or use an AI coding assistant to help identify the issue</li></ol><h3 id="Q2-Blog-not-updating-after-push"><a href="#Q2-Blog-not-updating-after-push" class="headerlink" title="Q2: Blog not updating after push?"></a>Q2: Blog not updating after push?</h3><p><strong>Solution:</strong></p><ol><li>Check if Actions ran successfully (a green checkmark ✅ on the left indicates success)</li><li>Clear your browser cache and refresh</li><li>Sometimes it takes a few minutes for the compiled static pages to be fully deployed to the server; wait a few minutes and try again</li></ol><h3 id="Q3-How-do-I-bind-a-custom-domain"><a href="#Q3-How-do-I-bind-a-custom-domain" class="headerlink" title="Q3: How do I bind a custom domain?"></a>Q3: How do I bind a custom domain?</h3><p>If you plan to use a custom domain, you need to configure it in advance:</p><ol><li>Create a <code>CNAME</code> file (no extension) in the <code>source/</code> directory of your private repository</li><li>The file content should be your domain, for example:</li></ol><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">blog.yourdomain.com</span><br></pre></td></tr></table></figure><ol start="3"><li>Add a CNAME record at your domain registrar pointing to <code>username.github.io</code></li><li>Wait for DNS to propagate (may take a few hours)</li></ol><p>This way, every time you commit, the CNAME file will be copied to the <code>public/</code> directory and pushed to the public repository along with the build output</p><blockquote><p><strong>Note:</strong> The CNAME file should contain only one line with your domain name; no extra blank lines or content</p></blockquote><h3 id="Q4-Theme-configuration-changes-not-taking-effect"><a href="#Q4-Theme-configuration-changes-not-taking-effect" class="headerlink" title="Q4: Theme configuration changes not taking effect?"></a>Q4: Theme configuration changes not taking effect?</h3><p><strong>Solution:</strong></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">hexo clean <span class="comment"># Clear cache</span></span><br><span class="line">hexo generate <span class="comment"># Regenerate</span></span><br><span class="line">hexo server <span class="comment"># Start the server and check in your browser</span></span><br></pre></td></tr></table></figure><h3 id="Q5-How-do-I-back-up-my-blog"><a href="#Q5-How-do-I-back-up-my-blog" class="headerlink" title="Q5: How do I back up my blog?"></a>Q5: How do I back up my blog?</h3><p>A few suggestions:</p><ol><li>Periodically push to other Git platforms, such as a self-hosted Gitea instance</li><li>Keep a few copies on another device or NAS</li><li>Back up important configuration files separately</li></ol><h2 id="Conclusion"><a href="#Conclusion" class="headerlink" title="Conclusion"></a>Conclusion</h2><p>Congratulations, you now have a Hexo blog powered by GitHub Pages</p><p>Now, it’s time to start your writing journey!</p><hr><h2 id="References"><a href="#References" class="headerlink" title="References"></a>References</h2><ul><li><a href="https://hexo.io/docs/">Hexo Official Documentation</a></li><li><a href="https://docs.github.com/pages">GitHub Pages Documentation</a></li><li><a href="https://docs.github.com/actions">GitHub Actions Documentation</a></li><li><a href="https://markdown.com.cn/">Markdown Guide</a></li></ul>]]>
    </content>
    <id>https://blog.88889000.xyz/2026/tech/hexo-github-actions-github-pages/</id>
    <link href="https://blog.88889000.xyz/2026/tech/hexo-github-actions-github-pages/"/>
    <published>2026-03-05T20:34:20.000Z</published>
    <summary>A complete tutorial on using GitHub Actions to automatically deploy Hexo blog to GitHub Pages</summary>
    <title>Deploy Hexo Blog to GitHub Pages with GitHub Actions</title>
    <updated>2026-05-26T08:44:02.242Z</updated>
  </entry>
  <entry>
    <author>
      <name>MarchSnow</name>
    </author>
    <category term="Other" scheme="https://blog.88889000.xyz/categories/Other/"/>
    <content>
      <![CDATA[<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ <span class="built_in">echo</span> Hello, World!</span><br></pre></td></tr></table></figure>]]>
    </content>
    <id>https://blog.88889000.xyz/2026/other/hello%20world/</id>
    <link href="https://blog.88889000.xyz/2026/other/hello%20world/"/>
    <published>2026-03-05T14:14:00.000Z</published>
    <summary>
      <![CDATA[<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span clas]]>
    </summary>
    <title>Hello World</title>
    <updated>2026-05-26T08:44:02.242Z</updated>
  </entry>
</feed>
