banner
克喵爱吃卤面

喵落阁

光就是一切的意义!
telegram
github
qq
email
x
bilibili

Hexo Memo#

My Configuration#

  1. Hexo Version: hexo-cli: 4.3.2, hexo: 7.3.0 (current latest)
  2. Node.js Version: 22.16.0
  3. Git Version: 2.47.0.windows.2
  4. PNPM Version: 10.12.4
  5. Windows Version: 11

Install Node.js#

  1. Install the LTS version from the official website. Generally, the computer's memory is sufficient to install directly on the C drive, but you can change the path if needed. I have no issues downloading normally with a different path.

  2. After installation, check if it was successful. Press win + R on the keyboard, type CMD, and hit enter to open the CMD window. Execute the command node -v, and if you see the version information, it means the installation was successful.

Install Git#

Install the latest version of the 64-bit Git for Windows Setup package from the official website.

After installation, type git --version in the command line. If the version number is displayed, it means the installation was successful.

Common Commands#

git config -l  // View all configurations
git config --system --list // View system configurations
git config --global --list // View user (global) configurations

Configure Git Username and Email#

git config --global user.name "YourUsername"
git config --global user.email "YourEmail"

Install Package Manager#

Installing npm is the foundation for everything. Generally, if you install Node, you also install npm. Verify with the following commands:

npm -v
node -v

Change npm Source. npm downloads various modules from foreign servers by default, which can be slow. It is recommended to configure it to use the Taobao mirror. Open the CMD window and run the following command:

npm config set registry https://registry.npm.taobao.org

Install pnpm#

pnpm is a fast, disk space-saving package manager, similar to npm and yarn. You can install pnpm with the following command:

npm install -g pnpm

Why choose pnpm? Because it has a fast installation speed, more efficient dependency management, and compared to npm, I find npm often fails and is slow, while pnpm gives me a better experience.

Install Hexo#

  1. In Git BASH, enter the following command to install Hexo:
pnpm install -g hexo-cli
  1. After installation, enter hexo -v to verify if it was successful.

Github Configuration#

The above operations are prerequisites; next is configuring Github.

I won't elaborate on registering GitHub; it's basic knowledge that even I, a coding novice, understand.

Create Repository#

  1. Log in to GitHub, click the + icon in the upper right corner, and select New repository.
  2. Fill in the repository name, and it is recommended to use the format <username>.github.io (for example: yourusername.github.io), so it can directly serve as a personal homepage.

I do not plan to use the conventional hexo deploy command to deploy to GitHub Pages because as your articles increase, the generation time becomes cumbersome. The suggestion here is to use Github Actions for automatic deployment.

This part of the tutorial is based on the article by the store manager, but it is a bit outdated, so I made some changes (the images here are from Anzhi Yu):

  1. First, create a private repository to store the source code, referred to as hexo-source,
  2. Then generate a GitHub token:

Visit GitHub -> Avatar (top right) -> Settings -> Developer Settings -> Personal access tokens -> generate new token. The name of the created token can be arbitrary, but you must check the repo and workflows items.

Click link to generate

image
image

[!NOTE]

!!! The token will only be displayed this time; it cannot be viewed again later, so make sure you have recorded the token. If you forget it later, you will have to regenerate and reconfigure it.

  1. In the settings of the hexo-source repository, click settings -> actions -> General -> Workflow permissions
    • Check Read and write permissions, and also check Allow <span style="background:#FF0000;"></span>all actions and reusable workflows.
  2. In settings -> Secrets and variables -> Actions -> New repository secret add
  • GITHUBTOKEN: Place the token you just generated.

The above are prerequisites; next, you need to deploy hexo before you can continue to the next step.#

Initialize Hexo#

  1. Create a new folder locally, for example, hexo-solitude.
  2. Here, I use vscode to open this folder, then in the terminal, enter the following command to initialize Hexo:
hexo init (project name)

I usually do not fill it in; I can start directly in the folder. If you add a project name, then the next step is:

cd (project name)
  1. Install dependencies:
pnpm install

Then choose the theme you want. Here I use Solitude. I won't go into detail about the specific configuration; I'll just mention part of it:

First, the basic installation. Here I still choose git clone for no other reason; mainly, I will modify some source code. If you don't want to modify it, you can download it directly with pnpm:

// git installation
git clone -b dev https://github.com/everfu/hexo-theme-solitude.git themes/solitude

// pnpm installation
pnpm i hexo-theme-solitude

Then modify _config.yml to:

theme: solitude

Configuration#

The following code is my memo:

# Hexo Configuration
## Docs: https://hexo.io/docs/configuration.html
## Source: https://github.com/hexojs/hexo/

# Site
title: Meow Falling Pavilion
subtitle: 'Kemeow's Blog'
description: 'May you still love your family and friends after seeing all the truths.'
keywords: Kemeow, kemiao, blog
author: Kemeow loves to eat braised noodles
language: zh-CN
timezone: 'Asia/Shanghai'

# URL
## Set your site url here. For example, if you use GitHub Page, set url as 'https://username.github.io/project'
url: # Fill in the website address
permalink: posts/:abbrlink.html
permalink_defaults:
pretty_urls:
  trailing_index: true # Set to false to remove trailing 'index.html' from permalinks
  trailing_html: true # Set to false to remove trailing '.html' from permalinks

# Directory
source_dir: source
public_dir: public
tag_dir: tags
archive_dir: archives
category_dir: categories
code_dir: downloads/code
i18n_dir: :lang
skip_render:

# Writing
new_post_name: :title.md # File name of new posts
default_layout: post
titlecase: false # Transform title into titlecase
external_link:
  enable: true # Open external links in new tab
  field: site # Apply to the whole site
  exclude: ''
filename_case: 0
render_drafts: false
post_asset_folder: false
relative_link: false
future: true
syntax_highlighter: highlight.js
highlight:
  line_number: false
  auto_detect: false
  tab_replace: ''
  wrap: true
  hljs: false
prismjs:
  preprocess: true
  line_number: true
  tab_replace: ''

# Home page setting
# path: Root path for your blogs index page. (default = '')
# per_page: Posts displayed per page. (0 = disable pagination)
# order_by: Posts order. (Order by date descending by default)
index_generator:
  path: ''
  per_page: 10
  order_by: -date

# Category & Tag
default_category: uncategorized
category_map:
tag_map:

# Metadata elements
## https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta
meta_generator: true

# Date / Time format
## Hexo uses Moment.js to parse and display date
## You can customize the date format as defined in
## http://momentjs.com/docs/#/displaying/format/
date_format: YYYY-MM-DD
time_format: HH:mm:ss
## updated_option supports 'mtime', 'date', 'empty'
updated_option: 'mtime'

# Pagination
## Set per_page to 0 to disable pagination
per_page: 10
pagination_dir: page

# Include / Exclude file(s)
## include:/exclude: options only apply to the 'source/' folder
include: []
exclude: []
ignore: []

# Extensions
## Plugins: https://hexo.io/plugins/
## Themes: https://hexo.io/themes/
theme: solitude

# Deployment
## Docs: https://hexo.io/docs/one-command-deployment
deploy:
  type: git
  repo: [email protected]:kemiaofxjun/kemiaofxjun.github.io.git
  branch: main

# RSS Feed Configuration
feed:
  type: atom          # Generate atom.xml
  path: atom.xml      # Output file name
  limit: 20           # Maximum number of articles displayed (0=all)
  hub:                # PubSubHubbub hub (optional)
  content: true       # Whether to include full content (true=yes, false=summary only)
  content_limit: 140  # Summary length (effective when content=false)
  content_limit_delim: ' '  # Truncation delimiter
  order_by: -date     # Sort by date in descending order
  autodiscovery: true # Add auto-discovery tag in HTML head

# Math formula rendering configuration
markdown:
  preset: 'default' # MD syntax used, default is GFM
  render:
    html: true # Render html
    xhtmlOut: false
    langPrefix: 'language-' # Add prefix to class names in code blocks (when specifying language).
    breaks: true
    linkify: true # If you write a link instead of [name](link), it will automatically recognize it as a link and render it.
    typographer: true # Replace common typographic elements.
    quotes: '“”‘’' # Replace article quotes with "" ''
  enable_rules:
  disable_rules:
  plugins: # Use plugins
  anchors:
    level: 2 # Render heading levels (h1,h2,h3)
    collisionSuffix: ''
    permalink: true
    permalinkClass: 'headerlink'
    permalinkSide: 'left'
    permalinkSymbol: ''
    case: 0
    separator: '-'
  images: # Some compilation for images
    lazyload: true # Whether to render lazyload
    prepend_root: false
    post_asset: false
  inline: false

swpp:
  # Whether to enable the plugin
  enable: true
  # Whether to automatically execute scripts before publishing
  auto_exec: true
  gen_dom: true

# Article link conversion to numbers or letters: https://github.com/rozbo/hexo-abbrlink
abbrlink:
    alg: crc16   # Algorithm: crc16(default) and crc32
    rep: hex     # Base: dec(default) and hex: dec # Output base: decimal and hexadecimal, default is decimal. | dec is decimal, hex

# https://github.com/hexojs/hexo-generator-sitemap
sitemap:
  path: sitemap.xml
  rel: false
  tags: true
  categories: true

algolia:
  appId: ""
  apiKey: ""
  adminApiKey: ""
  chunkSize: 5000
  indexName: "index-name"
  fields:
    - content:strip:truncate,0,500
    - excerpt:strip
    - gallery
    - permalink
    - photos
    - slug
    - tags
    - title

# hexo-safego security redirection plugin
# see https://blog.liushen.fun/posts/1dfd1f41/
hexo_safego:
  # Basic function settings
  general:
    enable: true                # Enable plugin
    enable_base64_encode: true  # Use Base64 encoding
    enable_target_blank: true   # Open redirection page in a new window

  # Security settings
  security:
    url_param_name: 'u'         # URL parameter name
    html_file_name: 'go.html'   # Redirect page file name
    ignore_attrs:               # HTML structures to ignore
      - 'data-fancybox'

  # Container and page settings
  scope:
    apply_containers:           # Applied container selectors
      - '#article-container'
    apply_pages:                # Applied page paths
      - "/posts/"
      - "/devices/"
    exclude_pages:              # Excluded page paths

  # Domain whitelist
  whitelist:
    domain_whitelist:           # Allowed whitelist domains, implemented through string matching
      - "kemeow.top"
      - "kemiaosw.top"
      - "050815.xyz"
      - "314926.xyz"
      - "051531.xyz"

  # Page appearance settings
  appearance:
    avatar: https://img.314926.xyz/images/2025/08/13/no-background-kemiaofxjun.webp   # Redirection page avatar path
    title: "Meow Falling Pavilion"            # Redirection page title
    subtitle: "Security Center"         # Redirection page subtitle
    darkmode: auto              # Whether to enable dark mode
    countdowntime: 4            # Countdown seconds for redirection page; if set to a negative number, it will not auto-redirect

  # Debug settings
  debug:
    enable: false               # Enable debug mode

# Anime tracking plugin
# https://github.com/HCLonely/hexo-bilibili-bangumi
bangumi: # Anime tracking settings
  enable: true
  source: bili
  path: 
  vmid: 3546643173477234
  title: "Anime Tracking List"
  quote: "Life goes on, and so does anime tracking!"
  show: 1
  lazyload: false
  loading:
  showMyComment: true
  pagination: false
  extra_options:
    top_img: false
    lazyload:
      enable: false

Other modifications to the blog mainly come from tutorials and some bloggers' websites.


Plugins#

  1. Basic Dependency hexo-renderer-pug
pnpm i hexo-renderer-pug

  1. Word Count hexo-wordcount
pnpm i hexo-wordcount

Modify in the configuration:

# --------------------------- start ---------------------------
# Word count
# Word count statistics
# warning: Please install the hexo-wordcount plugin first.
# Warning: Please install the hexo-wordcount plugin first.
wordcount: false
# --------------------------- end ---------------------------

  1. Math Formulas Uninstall hexo-render-marked
npm un hexo-renderer-marked

Install hexo-renderer-markdown-it katex @renbaoshuo/markdown-it-katex

pnpm i hexo-renderer-markdown-it katex @renbaoshuo/markdown-it-katex

Modify in the configuration

# --------------------------- start ---------------------------
# Katex
# Latex formula support
# Latex formula support
katex:
  enable: false
  # Whether to load on each page
  # Whether to load on each page
  per_page: false
  # Whether to enable copy formula
  # Whether to enable copy formula
  copytex: false
# --------------------------- end ---------------------------

Add the following content to _config.yml

markdown:
  preset: 'default'
  render:
    html: true
    xhtmlOut: false
    langPrefix: 'language-'
    breaks: true
    linkify: true
    typographer: true
    quotes: '“”‘’'
  enable_rules:
  disable_rules:
  plugins:
    - '@renbaoshuo/markdown-it-katex'
  anchors:
    level: 2
    collisionSuffix: ''
    permalink: false
    permalinkClass: 'header-anchor'
    permalinkSide: 'left'
    permalinkSymbol: '¶'
    case: 0
    separator: '-'
  images:
    lazyload: false
    prepend_root: false
    post_asset: false
  inline: false  # https://markdown-it.github.io/markdown-it/#MarkdownIt.renderInline

Enable the configuration option

# --------------------------- start ---------------------------
# Katex
# Latex formula support
# Latex formula support
katex:
  enable: true
  # Whether to load on each page
  # Whether to load on each page
  per_page: true
  # Whether to enable copy formula
  # Whether to enable copy formula
  copytex: false
# --------------------------- end ---------------------------


  1. PWA Install hexo-swpp and swpp-backends plugins

Execute in the blog root directory

pnpm i hexo-swpp 

pnpm i swpp-backends

Enable the configuration

# Around line 773
# --------------------------- start ---------------------------
# PWA
# Progressive Web App
pwa:
  enable: true
  manifest: /manifest.json # manifest.json
  theme_color: "#006a73" # Theme color
  mask_icon: /img/pwa/favicon.png # Mask icon
  apple_touch_icon: /img/pwa/favicon.png # Apple touch icon
  bookmark_icon: /img/pwa/favicon.png # Bookmark icon
  favicon_32_32: /img/pwa/favicon_32.png # 32x32 icon
  favicon_16_16: /img/pwa/favicon_16.png # 16x16 icon
# --------------------------- end ---------------------------

Create a manifest.json file in the source directory

{
    "name": "Website Name",
    "short_name": "Website Abbreviation",
    "theme_color": "#006a73",
    "background_color": "#006a73",
    "display": "fullscreen",
    "scope": "/",
    "start_url": "/",
    "id": "/",
    "icons": [
      {
        "src": "/img/pwa/favicon_16.png",
        "sizes": "16x16",
        "type": "image/png",
        "purpose": "any"
      },
      {
        "src": "/img/pwa/favicon_16.png",
        "sizes": "16x16",
        "type": "image/png",
        "purpose": "maskable"
      },
      {
        "src": "/img/pwa/favicon_32.png",
        "sizes": "32x32",
        "type": "image/png",
        "purpose": "any"
      },
      {
        "src": "/img/pwa/favicon_32.png",
        "sizes": "32x32",
        "type": "image/png",
        "purpose": "maskable"
      },
      {
        "src": "/img/pwa/favicon.png",
        "sizes": "180x180",
        "type": "image/png",
        "purpose": "any"
      },
      {
        "src": "/img/pwa/favicon.png",
        "sizes": "180x180",
        "type": "image/png",
        "purpose": "maskable"
      }
    ],
    "splash_pages": null
}

Create a sw-rules.js file in the blog root directory

module.exports.config = {
  /** @type {?ServiceWorkerConfig|boolean} */
  serviceWorker: {
    escape: 1,
    cacheName: 'SolitudeCache',
    debug: false,
  },
  register: {
    onsuccess: undefined,
    onerror: () =>
      console.error(
        'Service Worker registration failed! This may be due to your browser not supporting this feature!'
      ),
    builder: (root, framework, pluginConfig) => {
      const { onerror, onsuccess } = pluginConfig.register;
      return `
            <script>
                (() => {
                    const sw = navigator.serviceWorker;
                    const error = ${onerror && onerror.toString()};
                    if (!sw?.register('${new URL(root).pathname}sw.js')
                        ${onsuccess ? `?.then(${onsuccess.toString()})` : ""}
                        ?.catch(error)
                    ) error()
                })()
            </script>`;
    },
  },
  /** @type {?DomConfig|boolean} */
  dom: {
    /** @type {?VoidFunction} */
    onsuccess: () => {
      caches
        .match('https://id.v3/')
        .then((res) => {
          if (res)
            res.json().then((json) => {
              utils &&
                utils.snackbarShow(
                  `Cache refreshed, updated to version ${json.escape + '.' + json.global + '.' + json.local
                  } latest content`,
                  false,
                  2500
                );
            });
          else console.info('Cache not found');
        })
        .catch((error) => console.error('Cache matching error', error));
    },
  },
  /** @type {?VersionJsonConfig|boolean} */
  json: {
    /** @type {number} */
    maxHtml: 15,
    /** @type {number} */
    charLimit: 1024,
    /** @type {string[]} */
    merge: [],
    exclude: {
      /** @type {RegExp[]} */
      localhost: [],
      /** @type {RegExp[]} */
      other: [],
    },
  },
  /** @type {?ExternalMonitorConfig|boolean} */
  external: {
    /** @type {number} */
    timeout: 5000,
    /** Concurrency limit when fetching files */
    concurrencyLimit: 100,
    /** @type {({head: string, tail: string}|function(string):string[])[]} */
    js: [],
    /** @type {RegExp[]} */
    stable: [
      /^https:\/\/npm\.elemecdn\.com\/[^/@]+\@[^/@]+\/[^/]+\/[^/]+$/,
      /^https:\/\/cdn\.cbd\.int\/[^/@]+\@[^/@]+\/[^/]+\/[^/]+$/,
      /^https:\/\/cdn\.jsdelivr\.net\/npm\/[^/@]+\@[^/@]+\/[^/]+\/[^/]+$/,
    ],
    replacer: (srcUrl) => {
      if (srcUrl.startsWith('https://cdn.jsdelivr.net/npm/')) {
        const pathname = new URL(srcUrl).pathname;
        return [
          srcUrl,
          `https://cdn.cbd.int/${pathname}`,
          `https://npm.elemecdn.com/${pathname}`,
          `https://fastly.jsdelivr.net/npm/${pathname}`,
        ];
      } else {
        return srcUrl;
      }
    },
  },
};

module.exports.cacheRules = {
  simple: {
    clean: true,
    search: false,
    match: (url, $eject) =>
      url.host === $eject.domain && ['/404.html'].includes(url.pathname),
  },
  cdn: {
    clean: true,
    match: (url) =>
      [
        'cdn.cbd.int',
        'lf26-cdn-tos.bytecdntp.com',
        'lf6-cdn-tos.bytecdntp.com',
        'lf3-cdn-tos.bytecdntp.com',
        'lf9-cdn-tos.bytecdntp.com',
        'cdn.staticfile.org',
        'npm.elemecdn.com',
      ].includes(url.host) &&
      url.pathname.match(/\.(js|css|woff2|woff|ttf|cur)$/),
  },
};

module.exports.getSpareUrls = (srcUrl) => {
  if (srcUrl.startsWith('https://npm.elemecdn.com')) {
    return {
      timeout: 3000,
      list: [
        srcUrl,
        `https://fastly.jsdelivr.net/${new URL(srcUrl).pathname}`,
      ],
    };
  }
};

module.exports.ejectValues = (hexo, rules) => {
  return {
    domain: {
      prefix: 'const',
      value: new URL(hexo.config.url).host,
    },
  };
};

module.exports.skipRequest = (request) => request.url.startsWith("https://i0.hdslb.com") ||
  request.url.startsWith('https://meting.qjqq.cn') ||
  request.url.startsWith('https://api.i-meto.com');

  1. hexo-deploy-git Plugin for submitting to git
pnpm i hexo-deploy-git --save

  1. hexo-generator-feed Hexo's RSS plugin
pnpm i hexo-generator-feed --save

  1. Hexo's Short Links: hexo-abbrlink
pnpm i hexo-abbrlink --save

In _config.yml, modify:

permalink: posts/:abbrlink/ 
# or
permalink: posts/:abbrlink.html

Add:

# abbrlink config
abbrlink:
  alg: crc32      # Algorithm used to calculate abbrlink. Support crc16(default) and crc32
  rep: hex        # Representation of abbrlink in URLs. Support dec(default) and hex
  drafts: false   # Whether to generate abbrlink for drafts. (false by default)
  force: false    # Enable force mode. In this mode, the plugin will ignore the cache and calculate the abbrlink for every post even if it already had an abbrlink. (false by default)
  writeback: true # Whether to write changes to front-matters back to the actual markdown files. (true by default)

  1. Blog Sitemap : hexo-generator-sitemap
pnpm i hexo-generator-sitemap --save

In _config.yml, add configuration:

sitemap:
  path: 
    - sitemap.xml
    - sitemap.txt
  template: ./sitemap_template.xml
  template_txt: ./sitemap_template.txt
  rel: false
  tags: true
  categories: true

  1. Using Algolia Search : hexo-algoliasearch
  • Register for Algolia:

Registration address: dashboard.algolia.com/users/sign_up

  • Create an application:

After successful registration, create an application: dashboard.algolia.com/account/plan/create?from=dashboard

  • Search -> Configure -> Index, just add index_name

Execute the command in the blog:

pnpm i hexo-algoliasearch --save

Add to _config.yml

algolia:
  appId: "Z7A3XW4R2I"
  apiKey: "12db1ad54372045549ef465881c17e743"
  adminApiKey: "40321c7c207e7f73b63a19aa24c4761b"
  chunkSize: 5000
  indexName: "my-hexo-blog"
  fields:
    - content:strip:truncate,0,500
    - excerpt:strip
    - gallery
    - permalink
    - photos
    - slug
    - tags
    - title

[!NOTE]

!!! After configuration is complete, remember to run hexo clean

After hexo g, execute the following code:

hexo algolia

  1. hexo-safego Security redirection plugin

Before using this plugin, you need to install cheerio, which is a lightweight library for quickly and flexibly implementing core jQuery functionality on the server side. In the hexo-safego plugin, cheerio is used to parse and manipulate the generated static HTML content, similar to using jQuery to handle DOM elements in the browser. This allows the plugin to handle and replace external links when generating static pages, enhancing the blog's security without needing to introduce jQuery on the client side. Hexo generally has this plugin; you can check in node_modules. If not, please execute:

pnpm i cheerio --save

Then you can install this plugin:

pnpm i hexo-safego --save

Add the following configuration in the _config.yml file in the root directory of hexo:

# hexo-safego security redirection plugin
# see https://blog.liushen.fun/posts/1dfd1f41/
hexo_safego:
  # Basic function settings
  general:
    enable: true                # Enable plugin
    enable_base64_encode: true  # Use Base64 encoding
    enable_target_blank: true   # Open in a new window
  # Security settings
  security:
    url_param_name: 'u'         # URL parameter name
    html_file_name: 'go.html'   # Redirect page file name
    ignore_attrs:               # HTML attributes to ignore
      - 'data-fancybox'
  # Container and page settings
  scope:
    apply_containers:           # Applied container selectors
      - '#article-container'
    apply_pages:                # Applied page paths
      - "/posts/"
      - "/devices/"
    exclude_pages:              # Excluded page paths
  # Domain whitelist
  whitelist:
    domain_whitelist:           # Allowed whitelist domains
      - "qyliu.top"
      - "liushen.fun"
  # Page appearance settings
  appearance:
    avatar: /info/avatar.ico    # Avatar path
    title: "Qing Yu Fei Yang"            # Page title
    subtitle: "Security Center"         # Page subtitle
    darkmode: true              # Whether to enable dark mode
    countdowntime: -1           # Countdown seconds
  # Debug settings
  debug:
    enable: false               # Enable debug mode
  1. Hexo's Anime Tracking Page: hexo-bilibili-bangumi
pnpm i hexo-bilibili-bangumi --save

In _config.yml, configure:

bangumi: # Anime tracking settings
  enable: true           # Whether to enable
  source: bili          # Data source
  path: bangumis/index.html  # Page path
  vmid:                 # User ID
  title: 'Anime Tracking List'      # Page title
  quote: 'Life goes on, and so does anime tracking!' # Page quote
  show: 1              # Initial display page: 0=want to watch, 1=watching, 2=watched
  lazyload: true       # Whether to enable image lazy loading
  metaColor:           # Meta information font color
  color:               # Introduction font color
  webp: true          # Whether to use webp format images
  progress: true      # Whether to show progress bar
  ...
cinema: # Drama tracking settings
  enable: true           # Whether to enable
  source: bili
  ...
game: # Game settings, only supports source: bgmv0
  enable: true           # Whether to enable
  source: bgmv0
  ...

Still updating...


Github Action Configuration#

Continuing from the paragraph, there may be a next chapter pitfall in the future.

Next, create a private repository. According to the article by the big guy, it is to protect the Token, which is subjective.

This private repository is established to store Hexo blog code. If you want to use Qexo

This is also essential!

image

After creation, you need to push the blog's source code here. First, get the remote repository address; both SSH and HTTPS are acceptable here. SSH does not require entering a password on devices that have bound the SSH key, while HTTPS requires entering a password. However, SSH occasionally encounters port occupation issues. Please choose accordingly.

image

[!TIP]

The reason for using a private repository here is that the Token will be used in the upcoming configuration. If the Token is stolen, others can freely manipulate your GitHub repository content. To avoid this risk, the blog source code is kept closed.

Configure Github Action#

  1. In [Blogroot], create a .github folder, note that it starts with a .. Then create a workflows folder inside .github, and then create autodeploy.yml inside the workflows folder. Enter the following in [Blogroot]/.github/workflows/autodeploy.yml
# When there are changes pushed to the main branch, start Action
name: Auto Deployment

on:
  push:
    branches:
      - main # Your selected branch

  release:
    types:
      - published

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Check Branch
        uses: actions/checkout@v4
        with:
          ref: main # Your selected branch

      - name: Install Node
        uses: actions/setup-node@v4
        with:
          node-version: "22.x" # Node version

      - name: Install Hexo
        run: |
          export TZ='Asia/Shanghai'
          npm install hexo-cli -g
          npm install yamljs --save

      - name: Cache Hexo
        uses: actions/cache@v4
        id: cache
        with:
          path: node_modules
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}

      - name: Install Dependencies
        if: steps.cache.outputs.cache-hit != 'true'
        run: |
          npm install --save
          npm install hexo-algoliasearch --save
          npm install hexo-bilibili-bangumi --save

      - name: Generate Static Files
        run: |
          node ./link.js
          hexo clean
          hexo generate
          hexo bangumi -u
          hexo algolia

      - name: Deploy
        run: |
          cd ./public
          git init -b main
          git config --global user.name '${{ secrets.GITHUBUSERNAME }}'
          git config --global user.email '${{ secrets.GITHUBEMAIL }}'
          git add .
          git commit -m "${{ github.event.head_commit.message }} $(date +"%Z %Y-%m-%d %A %H:%M:%S") Updated by GitHub Actions"
          git push --force --quiet "https://${{ secrets.GITHUBUSERNAME }}:${{ secrets.GITHUBTOKEN }}@github.com/${{ secrets.GITHUBUSERNAME }}/${{ secrets.GITHUBUSERNAME }}.github.io.git" main

The above code is modified from the store manager for personal use. Why not use Anzhi Yu?

  1. First, placing the Token directly in the repository file is not ideal.

  2. For someone like me who is working locally, I cannot push to the repository because the token cannot be uploaded directly. I tried changing token: to token: ${{ servets.GH_token }}, but still encountered various issues. On the contrary, after using the store manager's code, it was almost perfect. After consulting AI, I got the current code, and it can be uploaded officially now (no offense intended).

  3. After that, you need to go to the repository's Settings -> Secrets -> actions to add environment variables. The variable names refer to those appearing in the script, and add them one by one.

image

Reset Remote Repository and Branch#

🍼 First time using git to manage blog source code 1. Delete or move the `.git` folder in `[Blogroot]/themes/solitude` to a non-blog folder. The reason is that the existence of the `.git` folder in the theme folder will cause it to be recognized as a subproject, making it impossible to upload to the source code repository.
  1. In the blog root directory [Blogroot], run the command:
git init # Initialize
git remote add origin [email protected]:[GithubUsername]/[SourceRepo].git #[SourceRepo] is the GitHub private repository for storing the source code
git checkout -b master # Switch to the master branch,
# After October 2020, the default branch for new GitHub repositories changed to main, be sure to change it
# If not, remember to keep all subsequent settings consistent with the branch
  1. Add ignore items
.DS_Store
Thumbs.db
db.json
*.log
node_modules/
public/
.deploy*/
.deploy_git*/
.idea
themes/solitude/.git

If it is not the solitude theme, remember to replace the last line with your currently used theme.
4. Then run the git commit command to submit the blog source code to GitHub.

git add .
git commit -m "github action update"
git push origin master
# After October 2020, the default branch for new GitHub repositories changed to main, be sure to change it
  1. If your theme folder has been uploaded correctly, and you have also added the .git folder in the theme folder to the ignore list, you can consider putting back or deleting the .git that you moved in step two for future upgrades (I can't help but wonder if anyone would actually use this method to upgrade).
🍾 Previously managed source code with git 1. Add ignore items

Since the content that can be installed via commands does not include what needs to be submitted to the source code, we need to add these items to the ignore list to indicate that they should not be uploaded to GitHub. This can significantly reduce the number of files to be submitted and speed up the submission process.
Open [Blogroot]/.gitignore, and enter the following content:

.DS_Store
Thumbs.db
db.json
*.log
node_modules/
public/
.deploy*/
.deploy_git*/
.idea
themes/solitude/.git

If it is not the solitude theme, remember to replace the last line with your currently used theme.

  1. Submit the source code to the private repository [SourceRepo]
    In the blog root directory [Blogroot], open the terminal and use git commands to reset the repository address. This way, when creating a new repository, we can still retain precious commit history for version rollback.
git remote rm origin # Remove the original repository link
git remote add origin [email protected]:[GithubUsername]/[SourceRepo].git #[SourceRepo] is the new GitHub private repository for storing the source code
git checkout -b master # Switch to the master branch,
# After October 2020, the default branch for new GitHub repositories changed to main, be sure to change it
# If not, remember to keep all subsequent settings consistent with the branch
git add .
git commit -m "github action update"
git push origin master
# After October 2020, the default branch for new GitHub repositories changed to main, be sure to change it
  1. Possible bugs
    Due to the existence of the .git folder in the solitude theme folder, the theme folder will be recognized as a subproject, making it impossible to upload to the source code repository. If you encounter issues with adding ignore items but still cannot upload the theme folder correctly, please first move the themes folder in the local source code to another directory. Then commit once. After that, move the themes folder back and commit again.

Important

If it still doesn't work, delete the .git folder in the solitude theme folder, and then repeat the above commit operation.

Digging Pits#

I've written roughly this far. Perhaps there will be a next chapter pitfall in the future? But for now, the general information ends here, and I will write a simple usage method for Qexo, some configuration changes for solitude, and my experiences in pitfalls later.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.