Preface

I recently planned to upgrade the theme of my blog. Since I was playing around with Github Actions, I planned to use it to implement CICD. After writing and submitting the article, the static files generated by hugo will be automatically deployed to Github pages, Netlify, Vercel, Cloud flare Pages and other third-party platforms. Today, I will record the automatic deployment process of Github pages, which will save a lot of trouble.

Since the Hugo static website generator used by the website involves sensitive configuration, I will put the source code of Hugo in a private warehouse, and then put the front-end static pages generated by Hugo in the Github public warehouse. In this way, we need to prepare two Github warehouses, and then implement CICD through github actions in the private warehouse.

Github Actions official documentation: https://docs.github.com/zh/actions

Github Pages official standard: https://pages.github.com/

Github Token configuration

Since it involves deployment, authentication will be used in this process, and Github provides three token authentication methods:

  • github_token
  • deploy_key
  • personal_token

In fact, in each workflow, GitHub will automatically create a unique GITHUB_TOKEN key for workflow authentication. GITHUB_TOKEN will expire when the job is completed or up to 24 hours later. This is a temporary authentication strategy.

Note: Since we are here involving cross-warehouse deployment, github_token cannot be used.

For more github_token, please refer to: https://docs.github.com/actions/security-guides/automatic-token-authentication

personal_token is mainly used to generate tokens with personal accounts.

https://github.com/settings/tokens

For deploy_token, you mainly generate a key pair yourself, attach the public key to the github repository, and store the private key yourself.

For more deploy_token references: https://docs.github.com/en/authentication/connecting-to-github-with-ssh/managing-deploy-keys

Here we use the deploy_token method for authentication, attaching the public key to the deploy-token of the public repository and the private key to the secret of the private repository.

Create deploy_token

1
2
ssh-keygen -t rsa -b 4096 -C "$(git config user.email)" -f gh-pages-wzdushu -N ""
# The key pair gh-pages-wzdushu and gh-pages-wzdushu.pub will be generated in the current directory

Public repository wzdushu/wzdushu.github.io configures Deploy keys and sets the content of gh-pages-wzdushu.pub.

Create a secret in a private repository, specify the name: ACTIONS_DEPLOY_KEY The content is gh-pages-wzdushu

github-actions-deploy-key

Github Actions configuration

Create a workflow in a private repository, my path here is: .github/workflows/cicd.yml, edit this file as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
name: Deploy Hugo site to Pages

on:
# Runs on pushes targeting the default branch
push:
branches: ["master"]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write

# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. concurrency: group: "pages" cancel-in-progress: false # Default to bash defaults: run: shell: bash jobs: # Build job and Deploy hugo to pages build-deploy: runs-on: ubuntu-latest env: HUGO_VERSION: 0.121.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 - name: Install Dart Sass run: sudo snap install dart-sass - name: Checkout uses: actions/checkout@v4 with: submodules: recursive - name: Build with Hugo env: HUGO_CACHEDIR: ${{ runner.temp }}/hugo_cache HUGO_ENVIRONMENT: production run: | hugo \ --minify \ --baseURL "${{ steps.pages.outputs .base_url }}/" - name: Upload artifact uses: actions/upload-pages-artifact@v2 with: path: ./public - name: Deploy to GitHub Pages uses: peaceiris/actions-gh-pages@v4 with: deploy_key: ${{ secrets.ACTIONS_DEPLOY_KEY }} external_repository: wzdushu/wzdushu.github.io
publish_dir: ./public
publish_branch: master
cname: wnote.com
commit_message: ${{ github.event.head_commit.message }}

on There are three triggering methods here:

  • push: execute when git push is pushed.
  • workflow_dispatch: manually execute the actions of the project repository.
  • schedule: scheduled execution

Since the new version of the hugo theme here depends on Sass, it needs to be installed here, which is not required for everyone.

The deployment here does not use the official actions, but uses the open source peaceiris/actions-gh-pages, mainly because this repository is more friendly to Hugo, MkDocs, Gatsby, mdBook, Next, Nuxt, etc.

For other configurations, please refer to the official documentation of github actions, and will not be explained one by one.

Execute deployment

Later, we happily submitted the article to Github as usual, triggered GitHub Actions to generate static files and pushed them to GitHub Pages, and spent the rest of the time drinking a cup of coffee and waiting for it to finish its work.

github-action-cicd

Summary: The function of Github actions to automatically deploy is not limited to deploying static pages today. For actual projects and production environments, applications are often deployed to k8s clusters or some other PAAS platforms, such as Alibaba Cloud ACK, AWS’s EKS, Azure ’s AKS, etc. Of course, Github Actions also has other functions similar to Jenkins or Gitlab CI.