使用Hugo+Github+Github Action构建个人技术博客,搭建技术博客的新方式!
前期准备
Hugo入门
本小结利用hugo快速创建一个可以在本地运行的博客工作区
- 创建站点
1
| $ hugo new site workspace
|
- 添加主题
1
2
| $ cd workspace
$ git clone https://github.com/olOwOlo/hugo-theme-even themes/even
|
- 拷贝配置
1
2
| # 当前目录为workspace
$ cp themes/even/exampleSite/config.toml .
|
- 添加文章
1
2
| # 当前目录为workspace
$ hugo new post/my-first-post.md
|
- 修改文章
1
2
| # 当前目录为workspace
$ vim content/post/my-first-post.md
|
1
2
3
4
5
6
| ---
title: "My First Post"
date: 2019-03-26T08:47:11+01:00
draft: true
---
This is my first post!
|
- 生成文件
1
2
| # 当前目录为workspace
$ hugo server -D
|
- 查看站点
创建Github远程库
我们需要两个Github库,一个私有库及一个公有库。
远程工作库
如下图所示,创建一个私有Github库用于存放博客的所有资源(源文件、图片等)。
注意
图中的库名并不重要,下文使用远程工作库指代该私有Github库。
远程博客库
其本质就是Github Pages库,库名格式必须符合<username>.github.io
要求且必须为公有库。
注意
库名很重要,务必把username
替换为你的Github用户名。下文使用远程博客库指代该Github库。
整体流程
- 使用Git托管Hugo工作区,使其成为本地工作库。
- 借助Git将本地工作库与远程工作库关联。
- 利用Github Action实现博客自动化发布到远程博客库。
- 将本地工作库推送到远程工作库触发Github Action工作流。
- 在Github Action工作流中生成博客文章并部署到远程博客库。
托管本地工作区
- 使用git将本地工作区变为本地工作库
1
2
| $ cd workspace
$ git init
|
- 将主题重新以git子模块的方式添加
1
2
| $ rm -rf themes/even
$ git submodule add https://github.com/olOwOlo/hugo-theme-even themes/even
|
- 创建本地工作库的main分支
1
2
| $ git add .
$ git commit -m "init git workspace"
|
关联远程工作库
- 关联本地工作库与远程工作库
1
2
3
4
5
6
7
8
| # 关联本地与远程工作库
$ git remote add origin https://github.com/longyue0521/workspace
# 设置本地库main分支追踪远程库main分支
$ git branch --set-upstream-to=origin/main main
# 查看远程工作库
$ git remote -v
|
- 同步本地工作库与远程工作库
1
2
3
4
5
6
7
8
9
10
11
12
| # 将远程工作区内容拉到本地
$ git pull --rebase origin main
# 来自 https://github.com/longyue0521/workspace
# * branch main -> FETCH_HEAD
# 成功变基并更新 refs/heads/main
# 将本地工作库内容推到远程
$ git push
# 或者使用下面的命令推送并关联
$ git push --set-upstream origin main
|
自动化部署博客
Github Action
为本地工作库添加Github Action工作流的方法很简单,只需要在本地工作库的.github/workflows
目录下添加格式为YAML的文件即可。
创建目录并添加配置文件
1
2
3
| $ cd workspace
$ mkdir -p .github/workflows
$ vim .github/workflows/gh-pages.yml
|
向gh-pages.yml
添加如下内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
| # Workflow to build and deploy site to Github Pages using Hugo
# Name of Workflow
name: Github Pages Deploy
# Controls when the action will run. Triggers the workflow on main request
# events but only for the master branch
on:
push:
branches:
- main
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "deploy"
deploy:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Step 1 - Checks-out your repository under $GITHUB_WORKSPACE
- name: Checkout
uses: actions/checkout@v2
with:
submodules: true # Fetch Hugo themes
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod
# Step 2 - Sets up the latest version of Hugo
- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: 'latest'
extended: true
# Step 3 - Clean and don't fail
- name: Clean public directory
run: rm -rf public
# Step 4 - Builds the site using the latest version of Hugo
- name: Builds site
run: hugo --minify
# Step 5 - Create README file
- name: Create README file
run: cp gojustfor.fun.md public/README.md
# Step 6 - Push our generated site to Github Pages Repo
- name: Deploy it!
uses: peaceiris/actions-gh-pages@v3
with:
deploy_key: ${{ secrets.GP_ACTIONS_DEPLOY_KEY }}
external_repository: longyue0521/longyue0521.github.io
publish_branch: main
publish_dir: ./public
#cname: gojustfor.fun
|
- 第4行,定义了工作流名。
- 第8——11行,将本地工作库main分支推送到远程工作库时触发第14行定义的工作。
- 第16行,定义了一个名为deploy的工作。
- 该工作运行在
ubuntu-latest
上 - 第一步,检出远程工作库,即上面
gh-pages.yml
所在私有Github库。 - 第二步,安装Hugo
- 第三步,清理博客文件
- 第四步,生成博客文件
- 第五步,拷贝README,可选
- 第六步,将博客文件部署到远程博客库
跨库部署博客
跨库部署的关键步骤定义在gh-pages.yml
中,详解如下:
1
2
3
4
5
6
7
8
| # Step 6 - Push our generated site to Github Pages Repo
- name: Deploy it!
uses: peaceiris/actions-gh-pages@v3
with:
deploy_key: ${{ secrets.GP_ACTIONS_DEPLOY_KEY }}
external_repository: longyue0521/longyue0521.github.io
publish_branch: main
publish_dir: ./public
|
- 这是一个名为
Deploy it!
的步骤 - 使用另一个Github Action工作流
peaceiris/actions-gh-pages@v3
- 用
deploy_key
将当前库publish_dir
目录下的内容部署到external_repository
库的publish_branch
分支。
由此可见deploy_key
是跨库部署的关键,这与用git通过SSH Key推送代码到Github库相类似。
- 本地生成密钥对
1
2
3
4
| $ ssh-keygen -t rsa -b 4096 -C "$(git config user.email)" -f gh-pages -N ""
# You will get 2 files:
# gh-pages.pub (public key)
# gh-pages (private key)
|
得到公钥gh-pages.pub
和私钥gh-pages
。
- 配置远程工作库
如下图所示,将gh-pages
私钥内容添加到远程工作库,添加路径为Settings > Secrets > New secret
。
注意
密钥名应为GP_ACTIONS_DEPLOY_KEY
与上文的${{ secrets.GP_ACTIONS_DEPLOY_KEY }}
对应
- 配置远程博客库
如下图所示,将gh-pages.pub
公钥内容添加到远程博客库,添加路径为Settings > Deploy keys > Add deploy key
。
注意
注意添加路径,并勾选 Allow write access
配置博客
整体配置
下面以Even主题为例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
| baseURL = "https://longyue0521.github.io"
languageCode = "zh-cn"
defaultContentLanguage = "zh-cn" # en / zh-cn / ... (This field determines which i18n file to use)
title = "Talent Is Enduring Patience"
preserveTaxonomyNames = true
enableRobotsTXT = true
enableEmoji = true
theme = "even"
enableGitInfo = false # use git commit log to generate lastmod record # 可根据 Git 中的提交生成最近更新记录。
# Syntax highlighting by Chroma. NOTE: Don't enable `highlightInClient` and `chroma` at the same time!
pygmentsOptions = "linenos=table"
pygmentsCodefences = true
pygmentsUseClasses = true
pygmentsCodefencesGuessSyntax = true
hasCJKLanguage = true # has chinese/japanese/korean ? # 自动检测是否包含 中文\日文\韩文
paginate = 5 # 首页每页显示的文章数
disqusShortname = "" # "outofmemory-me" # disqus_shortname
googleAnalytics = "" # UA-XXXXXXXX-X
copyright = "" # default: author.name ↓ # 默认为下面配置的author.name ↓
[author] # essential # 必需
name = "龍躍"
[sitemap] # essential # 必需
changefreq = "weekly"
priority = 0.5
filename = "sitemap.xml"
[[menu.main]] # config your menu # 配置目录
name = "首页" #"Home"
weight = 10
identifier = "home"
url = "/"
[[menu.main]]
name = "归档" #"Archives"
weight = 40
identifier = "archives"
url = "/post/"
[[menu.main]]
name = "标签" #"Tags"
weight = 30
identifier = "tags"
url = "/tags/"
[[menu.main]]
name = "分类" #"Categories"
weight = 20
identifier = "categories"
url = "/categories/"
[params]
version = "4.x" # Used to give a friendly message when you have an incompatible update
debug = false # If true, load `eruda.min.js`. See https://github.com/liriliri/eruda
since = "2017" # Site creation time # 站点建立时间
# use public git repo url to link lastmod git commit, enableGitInfo should be true.
# 指定 git 仓库地址,可以生成指向最近更新的 git commit 的链接,需要将 enableGitInfo 设置成 true.
gitRepo = ""
# site info (optional) # 站点信息(可选,不需要的可以直接注释掉)
logoTitle = "Go! Just for fun!" # default: the title value # 默认值: 上面设置的title值
keywords = ["Go", "K8s","Docker"]
description = "Talent Is Enduring Patience | Just For Fun"
# paginate of archives, tags and categories # 归档、标签、分类每页显示的文章数目,建议修改为一个较大的值
archivePaginate = 50
# show 'xx Posts In Total' in archive page ? # 是否在归档页显示文章的总数
showArchiveCount = true
# The date format to use; for a list of valid formats, see https://gohugo.io/functions/format/
dateFormatToUse = "2006-01-02"
# show word count and read time ? # 是否显示字数统计与阅读时间
moreMeta = true
# Syntax highlighting by highlight.js
highlightInClient = false
# 一些全局开关,你也可以在每一篇内容的 front matter 中针对单篇内容关闭或开启某些功能,在 archetypes/default.md 查看更多信息。
# Some global options, you can also close or open something in front matter for a single post, see more information from `archetypes/default.md`.
toc = true # 是否开启目录
autoCollapseToc = false # Auto expand and collapse toc # 目录自动展开/折叠
fancybox = true # see https://github.com/fancyapps/fancybox # 是否启用fancybox(图片可点击)
# mathjax
mathjax = false # see https://www.mathjax.org/ # 是否使用mathjax(数学公式)
mathjaxEnableSingleDollar = false # 是否使用 $...$ 即可進行inline latex渲染
mathjaxEnableAutoNumber = false # 是否使用公式自动编号
mathjaxUseLocalFiles = false # You should install mathjax in `your-site/static/lib/mathjax`
postMetaInFooter = true # contain author, lastMod, markdown link, license # 包含作者,上次修改时间,markdown链接,许可信息
linkToMarkDown = true # Only effective when hugo will output .md files. # 链接到markdown原始文件(仅当允许hugo生成markdown文件时有效)
contentCopyright = '<a rel="license noopener" title="国际许可(CC BY-NC-SA 4.0)"href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">"署名-非商业性使用-相同方式共享 4.0 国际"</a> 转载请保留作者及原文链接' # e.g. '<a rel="license noopener" href="https://creativecommons.org/licenses/by-nc-nd/4.0/" target="_blank">CC BY-NC-ND 4.0</a>'
changyanAppid = "" # Changyan app id # 畅言
changyanAppkey = "" # Changyan app key
livereUID = "" # LiveRe UID # 来必力
baiduPush = false # baidu push # 百度
baiduAnalytics = "" # Baidu Analytics
baiduVerification = "" # Baidu Verification
googleVerification = "" # Google Verification # 谷歌
# Link custom CSS and JS assets
# (relative to /static/css and /static/js respectively)
customCSS = []
customJS = []
uglyURLs = false # please keep same with uglyurls setting
[params.publicCDN] # load these files from public cdn # 启用公共CDN,需自行定义
enable = true
jquery = '<script src="https://cdn.jsdelivr.net/npm/jquery@3.2.1/dist/jquery.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>'
slideout = '<script src="https://cdn.jsdelivr.net/npm/slideout@1.0.1/dist/slideout.min.js" integrity="sha256-t+zJ/g8/KXIJMjSVQdnibt4dlaDxc9zXr/9oNPeWqdg=" crossorigin="anonymous"></script>'
fancyboxJS = '<script src="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.1.20/dist/jquery.fancybox.min.js" integrity="sha256-XVLffZaxoWfGUEbdzuLi7pwaUJv1cecsQJQqGLe7axY=" crossorigin="anonymous"></script>'
fancyboxCSS = '<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.1.20/dist/jquery.fancybox.min.css" integrity="sha256-7TyXnr2YU040zfSP+rEcz29ggW4j56/ujTPwjMzyqFY=" crossorigin="anonymous">'
timeagoJS = '<script src="https://cdn.jsdelivr.net/npm/timeago.js@3.0.2/dist/timeago.min.js" integrity="sha256-jwCP0NAdCBloaIWTWHmW4i3snUNMHUNO+jr9rYd2iOI=" crossorigin="anonymous"></script>'
timeagoLocalesJS = '<script src="https://cdn.jsdelivr.net/npm/timeago.js@3.0.2/dist/timeago.locales.min.js" integrity="sha256-ZwofwC1Lf/faQCzN7nZtfijVV6hSwxjQMwXL4gn9qU8=" crossorigin="anonymous"></script>'
flowchartDiagramsJS = '<script src="https://cdn.jsdelivr.net/npm/raphael@2.2.7/raphael.min.js" integrity="sha256-67By+NpOtm9ka1R6xpUefeGOY8kWWHHRAKlvaTJ7ONI=" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/flowchart.js@1.8.0/release/flowchart.min.js" integrity="sha256-zNGWjubXoY6rb5MnmpBNefO0RgoVYfle9p0tvOQM+6k=" crossorigin="anonymous"></script>'
sequenceDiagramsCSS = '<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/bramp/js-sequence-diagrams@2.0.1/dist/sequence-diagram-min.css" integrity="sha384-6QbLKJMz5dS3adWSeINZe74uSydBGFbnzaAYmp+tKyq60S7H2p6V7g1TysM5lAaF" crossorigin="anonymous">'
sequenceDiagramsJS = '<script src="https://cdn.jsdelivr.net/npm/webfontloader@1.6.28/webfontloader.js" integrity="sha256-4O4pS1SH31ZqrSO2A/2QJTVjTPqVe+jnYgOWUVr7EEc=" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/snapsvg@0.5.1/dist/snap.svg-min.js" integrity="sha256-oI+elz+sIm+jpn8F/qEspKoKveTc5uKeFHNNVexe6d8=" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/underscore@1.8.3/underscore-min.js" integrity="sha256-obZACiHd7gkOk9iIL/pimWMTJ4W/pBsKu+oZnSeBIek=" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/gh/bramp/js-sequence-diagrams@2.0.1/dist/sequence-diagram-min.js" integrity="sha384-8748Vn52gHJYJI0XEuPB2QlPVNUkJlJn9tHqKec6J3q2r9l8fvRxrgn/E5ZHV0sP" crossorigin="anonymous"></script>'
# Display a message at the beginning of an article to warn the readers that it's content may be outdated.
# 在文章开头显示提示信息,提醒读者文章内容可能过时。
[params.outdatedInfoWarning]
enable = false
hint = 30 # Display hint if the last modified time is more than these days ago. # 如果文章最后更新于这天数之前,显示提醒
warn = 180 # Display warning if the last modified time is more than these days ago. # 如果文章最后更新于这天数之前,显示警告
[params.gitment] # Gitment is a comment system based on GitHub issues. see https://github.com/imsun/gitment
owner = "" # Your GitHub ID
repo = "" # The repo to store comments
clientId = "" # Your client ID
clientSecret = "" # Your client secret
[params.utterances] # https://utteranc.es/
owner = "longyue0521" # Your GitHub ID
repo = "longyue0521.github.io" # The repo to store comments
[params.gitalk] # Gitalk is a comment system based on GitHub issues. see https://github.com/gitalk/gitalk
owner = "" # Your GitHub ID
repo = "" # The repo to store comments
clientId = "" # Your client ID
clientSecret = "" # Your client secret
# Valine.
# You can get your appid and appkey from https://leancloud.cn
# more info please open https://valine.js.org
[params.valine]
enable = false
appId = '你的appId'
appKey = '你的appKey'
notify = false # mail notifier , https://github.com/xCss/Valine/wiki
verify = false # Verification code
avatar = 'mm'
placeholder = '说点什么吧...'
visitor = false
[params.flowchartDiagrams]# see https://blog.olowolo.com/example-site/post/js-flowchart-diagrams/
enable = false
options = ""
[params.sequenceDiagrams] # see https://blog.olowolo.com/example-site/post/js-sequence-diagrams/
enable = false
options = "" # default: "{theme: 'simple'}"
[params.busuanzi] # count web traffic by busuanzi # 是否使用不蒜子统计站点访问量
enable = false
siteUV = true
sitePV = true
pagePV = true
[params.reward] # 文章打赏
enable = false
wechat = "/path/to/your/wechat-qr-code.png" # 微信二维码
alipay = "/path/to/your/alipay-qr-code.png" # 支付宝二维码
[params.social] # 社交链接
a-email = "mailto:longyueli0521@gmail.com"
#b-stack-overflow = "http://localhost:1313"
#c-twitter = "http://localhost:1313"
#d-facebook = "http://localhost:1313"
#e-linkedin = "http://localhost:1313"
#f-google = "http://localhost:1313"
g-github = "http://github.com/longyue0521"
h-weibo = "https://weibo.com/longyue521"
#i-zhihu = "http://localhost:1313"
#j-douban = "http://localhost:1313"
#k-pocket = "http://localhost:1313"
#l-tumblr = "http://localhost:1313"
#m-instagram = "http://localhost:1313"
#n-gitlab = "http://localhost:1313"
o-bilibili = "https://space.bilibili.com/86465982"
# See https://gohugo.io/about/hugo-and-gdpr/
[privacy]
[privacy.googleAnalytics]
anonymizeIP = true # 12.214.31.144 -> 12.214.31.0
[privacy.youtube]
privacyEnhanced = true
# see https://gohugo.io/getting-started/configuration-markup
[markup]
[markup.tableOfContents]
startLevel = 1
[markup.goldmark.renderer]
unsafe = true
# 将下面这段配置取消注释可以使 hugo 生成 .md 文件
# Uncomment these options to make hugo output .md files.
#[mediaTypes]
# [mediaTypes."text/plain"]
# suffixes = ["md"]
#
#[outputFormats.MarkDown]
# mediaType = "text/plain"
# isPlainText = true
# isHTML = false
#
#[outputs]
# home = ["HTML", "RSS"]
# page = ["HTML", "MarkDown"]
# section = ["HTML", "RSS"]
# taxonomy = ["HTML", "RSS"]
# taxonomyTerm = ["HTML"]
|
修改配色
修改Even主题配色需要修改even/assets/sass/_variables.scss
文件中相关变量的值。
在Github Action工作流配置文件.github/workflows/gh-pages.yml
中添如下内容使修改配色自动化。
1
2
3
4
5
6
7
8
9
| # Step 4 - Change theme/even's color
- name: Change color of even theme to Mint Green
run: sed -i "0,/'Default'/{s/'Default'/'Mint Green'/}" ./themes/even/assets/sass/_variables.scss
- name: Change color of code background to Mint Green
run: sed -i "0,/f5f5f5/{s/f5f5f5/eaf5e56c/}" ./themes/even/assets/sass/_variables.scss
- name: Change summary of all post to Mint Green
run: sed -i "0,/danger/{s/danger/success/}" ./content/post/*.md
|
添加评论
定制域名
修改工作流文件
修改Github Action工作流配置文件.github/workflow/gh-pages.yml
添加CNAME
文件。
1
2
3
4
5
6
7
8
9
10
| # Step 6 - Push our generated site to Github Pages Repo
- name: Deploy it!
uses: peaceiris/actions-gh-pages@v3
with:
deploy_key: ${{ secrets.GP_ACTIONS_DEPLOY_KEY }}
external_repository: longyue0521/longyue0521.github.io
publish_branch: main
publish_dir: ./public
# 添加CNAME域名
cname: gojustfor.fun
|
阿里云域名解析
使用ping命令,查看<username>.github.io
的IP地址
在阿里云的云解析DNS/域名解析页面添加域名
- 为域名添加解析记录,两条记录如下图所示
设置远程博客库
如下图所示,在远程博客库的Settings > Pages
页面设置自定义域名及安全协议。
Reference
文章作者
longyue0521
上次更新
2021-07-04
许可协议
本作品采用"知识共享署名-非商业性使用-禁止演绎4.0国际许可协议",非商业转载请注明出处并
保留作者及原文链接,商业转载请联系作者获取授权.