baicai

白菜

一个勤奋的代码搬运工!

Hugo + GitHub Action + Github Pages, Building a Blog for Automatic Publishing

My solution consists of the following two core parts:

  • Blog source repository, which manages the blog configuration and all .md source files for version control, and works with GitHub Action for automated deployment, generating static site and pushing it to the GitHub Pages blog publishing repository.
  • GitHub Pages blog publishing repository, which uses GitHub Pages to deploy the website and can be accessed using a custom domain through CNAME resolution.

Building a Blog with Hugo#

Hugo is a blog tool implemented in Go, using Markdown for article editing, generating static site files, supporting rich theme configuration, and allowing customization through plugins like comment systems embedded with JavaScript. In addition to Hugo, there are other options such as Gatsby, Jekyll, Hexo, Ghost, etc., which have similar implementation and usage, so you can choose according to your preference.

Installing Hugo#

I am using macOS, so I will install the hugo program using the recommended homebrew method from the official website. For other systems, please refer to the official documentation.

brew install hugo

After installation, use the following command to verify (check the version):

hugo version

Creating a Hugo Site#

hugo new site blog-demo

Configuring the Theme#

After creating our site, we need to configure the theme. The Hugo community has a wide range of themes to choose from. You can select your favorite style from the Themes menu on the official website, preview the effects, and then go to the theme project repository. Generally, there will be detailed installation and configuration instructions. Now, I will use the smol theme that I am currently using as an example to demonstrate the configuration process.

cd blog-demo
git clone  [email protected]:colorchestra/smol.git themes/smol
cd themes/smol
rm -rf .git

After initializing the basic theme configuration, we can configure the site details in the config.toml file. Please refer to the theme documentation for specific configuration options.

Refer to the content of config.toml:

theme = "smol"

Publishing a New Article#

hugo new posts/blog-test.md

Local Site Debugging#

Perform real-time debugging and preview locally.

hugo server

After running the server, we can access our local preview webpage through the browser at http://localhost:1313.

GITHUB PAGES Repository#

After setting up the GitHub Pages repository, you can configure your registered custom domain in the settings to point to the URL generated by GitHub Pages. In addition, you need to change the baseURL in the config.toml file of the blog site configuration to your custom domain.

Publishing the Blog with GitHub Pages#

Now we can access our GitHub Pages page using the custom domain we set up. Currently, because the project repository is empty, accessing it will result in a 404 page.

The static website generated by Hugo is hosted using the GitHub Pages service, so we need to upload the static web page files generated by Hugo to the GitHub Pages project repository.

Manual Publishing#

hugo
cd public

By default, Hugo will store the generated static web page files in the public/ directory. We can initialize the public/ directory as a git repository and associate it with our clin003/blog_html remote repository to push our web page static files.

git init
git remote add origin [email protected]:baicaime/meBlog
git add .
git commit -m "debug"
git push origin main

Push to the GitHub Pages repository, and wait a few minutes to access our blog site using our custom domain, which is consistent with the local debugging using hugo server.

Automatic Publishing#

Because our blog is based on GitHub and GitHub Pages, we can use the official GitHub Action for CI automatic publishing.
GitHub Action is a continuous integration and continuous delivery (CI/CD) platform that can be used to automate build, test, and deployment pipelines with simple configurations.

The configuration is located in the repository directory
.github/workflows
with the .yml extension. My GitHub Action configuration file is named
deploy.yml
and the example configuration for automatic publishing is as follows:

name: Deploy Hugo site to Pages
on:
  push:
    branches: [ "main" ]
  workflow_dispatch:
permissions:
  contents: read
  pages: write
  id-token: write
defaults:
  run:
    shell: bash
env:
  NAME: BLOG_push
  # Target repository format: username/repository
  TARGET_REPOSITORY_NAME: baicaime/meBlog
  # Sync temporary directory (optional)
  CLONE_DIR: tmp_public
  # Build temporary directory (optional)
  BUILD_DIR: tmp_build
  # Configure git username
  GIT_USERNAME: baicaime


jobs:
  # This workflow contains a single job called "build"
  build:    
    runs-on: ubuntu-latest
    env:
      HUGO_VERSION: 0.117.0    
    steps:
      - name: Install Hugo CLI
        run: |
          wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \
          && sudo dpkg -i ${{ runner.temp }}/hugo.deb
      - uses: actions/checkout@v3
      - name: Build with Hugo
        env:
          # For maximum backward compatibility with Hugo modules
          HUGO_ENVIRONMENT: production
          HUGO_ENV: production
        run: |
          hugo \
            --minify \
            --baseURL "${{ steps.pages.outputs.base_url }}/" \
            -d ${{ env.BUILD_DIR }}
      
      - name: Git Config
        run: |
          git config --global user.email "[email protected]"
          git config --global user.name "${{ env.GIT_USERNAME }}"
          echo "Git configuration completed"

      - name: Git clone
        run: |
          echo "Syncing target repository (start)"
          git clone --depth 1 https://github.com/${{ env.TARGET_REPOSITORY_NAME }}.git ${{ env.CLONE_DIR }} &> /dev/null
          echo "Syncing target repository (completed)"

      - name: Git push
        run: |
          cp -rf ${{ env.BUILD_DIR }}/*  ${{ env.CLONE_DIR }}/
          cd ${{ env.CLONE_DIR }}
          echo "${{ github.event.head_commit.message }} `date +%FT%T%z`" > _pub_time.html         
          git add .
          git commit --message "Update ${{ env.NAME }} from ${{ env.TARGET_REPOSITORY_NAME }} ${{ github.event.head_commit.message }}"
          git push -f -q https://oauth2:${{ secrets.GIT_TOKEN }}@github.com/${{ env.TARGET_REPOSITORY_NAME }}.git main
          echo  "git push  ${{ env.TARGET_REPOSITORY_NAME }} (completed)"

The on field specifies the triggering conditions for the GitHub Action. I have set it to push and workflow_dispatch:

  • push: When there is a push action in this project repository, the GitHub Action will be executed.
  • workflow_dispatch: It can be manually triggered in the Action toolbar of the GitHub project repository.

The jobs field specifies the tasks in the GitHub Action. We have set up a build task, and the runs-on field specifies the GitHub Action runtime environment, which is ubuntu-latest in our case.
The build task includes six main steps: Install Hugo CLI, Checkout, Build with Hugo, Git Config, Git clone, and Git push.
The run field contains the commands to be executed, and the uses field is a plugin in GitHub Action. We have used the actions/checkout plugin in this case.
In the Checkout step, you can configure the submodules value as true in the with field to synchronize the submodules of the blog source repository (such as theme modules). However, since we did not install the Hugo theme as a submodule, we do not need this parameter.

Changes needed in the deploy.yml file:#

Change TARGET_REPOSITORY_NAME to your own GitHub Pages repository, for example, mine is set to baicaime/meBlog.
Change GIT_USERNAME to the username of your GitHub Pages repository.

Because we need to push from the blog repository to an external GitHub Pages repository, specific permissions are required. You need to create a Token under your GitHub account at Settings - Developer settings - Personal access tokens.

The required permissions are:

Contents: read/write

After configuration, copy the generated Token (note: it will only appear once), and add it as a secret variable named GIT_TOKEN in the blog source repository's

Settings - secrets and variables - Actions

This way, the GitHub Action can access the Token.

Testing the Push#

After completing the above configuration, push the code to the repository to trigger the GitHub Action, which will automatically generate the blog pages and push them to the GitHub Pages repository.

After the GitHub Pages repository is updated, the official page deployment CI will be automatically triggered, achieving website publishing.

Now, whenever we finish editing the blog content using familiar Markdown syntax locally, we just need to push the code and wait a few minutes to access the updated website using our custom domain.

The above is the blog automatic deployment system I implemented using Hugo and GitHub Action. My implementation repository is located at baicaime/meBlog.

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