Hexo-Butterfly添加友链

思路

  • 友链通过Github仓库的方式对外开放,其他人可通过Fork仓库提交PR的方式添加友链信息
  • 友链信息仓库集成流水线,实现自动推包到NPM仓库
  • 博客站点通过CDN方式引用script,解析后渲染至页面上

实现

1. 注册NPM账号,初始化项目

npm (npmjs.com)

到NPM网站上注册账号

使用以下命令初始化npm项目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ npm init
# 按照提示填写信息即可,后面可以通过package.json修改

# 设置下镜像源
$ npm config set registry http://registry.npmjs.org

# 登录账户
$ npm adduser
Username: your name
Password: your password
Email: your email

# 检查是否登录成功
$ npm whoami
# 不成功则重新登陆下
$ npm login

.gitignore.npmignore文件

.gitignore文件用来忽略文件,不上传到Git仓库

.npmignore文件用来忽略文件,不随包发布

通过package.json里的files属性设置发布文件的白名单

优先级:files > .npmignore > .gitignore

1
2
3
4
# 完成内容编写后发布包
$ npm publish
# 如果提示包不能为private,需要执行下面的命令
$ npm publish --access public

2. 通过CDN访问

这里使用jsdelivr

地址格式:https://cdn.jsdelivr.net/npm/(your packagename)@(version)/(file)

不写版本号的话默认使用latest,即最新版本

3. 集成Github workflow

文档地址:关于工作流程 - GitHub Docs

仓库根目录的.github/workflows/目录创建yaml文件来定义工作流

现在创建一个名为blog-friend-link.yaml的文件定义工作流,该工作流用来自动解析仓库中的友链文件并进行自动发包,这样每次有代码更新即可自动发布最新的NPM包,博客通过链接即可获取到最新的友链信息了。

样例文件:

该文件定义了这样一个工作流:在指定branch、tag有pull_request时会触发,也可手动触发,其中包括一个名为publish的job,该job运行在ubuntu-latest系统上,且默认所有的step都在blog/friend-link目录下执行,该job包含5个step

  1. 使用actions/checkout@v3的action检出仓库,这样我们的job才可以访问到
  2. 使用actions/setup-node@v3的action初始化了一个node环境,便于后续使用npm命令和执行js代码
  3. 包含一条npm install的命令行命令,因为第2步已经初始化了node环境,所以可以使用npm install安装相关的依赖
  4. 执行build.sh脚本构建发包需要的文件
  5. 执行build.sh脚本进行发包
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
# This is a basic workflow to help you get started with Actions

name: blog-friend-link-CI

# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the "master" branch
pull_request:
branches: ["master", "v*", "release*"]
tags: ["v*"]

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

# 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 "build"
publish:
# The type of runner that the job will run on
runs-on: ubuntu-latest

defaults:
run:
working-directory: blog/friend-link

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v3

# Runs a single command using the runners shell
- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: "14.x"
registry-url: "https://registry.npmjs.org"

# Runs a set of commands using the runners shell
- name: Install dependencies
run: npm install

- name: Run build script
run: ./build.sh build

- name: Publish
# if: github.ref_name == 'master'
run: ./build.sh publish
env:
COMMIT_ID: ${{ github.sha }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

注意:

  1. 第2步需要指定registry-url,不然后续发包会报404
  2. 第5步的发包需要传递NPM_TOKEN,而不是使用命令行登录的方式
生成NPM TOKEN

到NPM主页点击右上角头像(未登录请先登录)找到Access Tokens点击进入

1662042180529

点击Generate New Token到生成新的Token的页面

1662042264055

生成后返回Token列表会在表格头上显示Token,点击即可复制

添加NPM TOKEN到Github

到Github仓库页面点击Settings后选择Secrets里的Actions

1662042405123

点击New repository secret去添加新的密钥

1662042461474

注意:这里填写的Name和你在workflow定义文件中的需要一致

定义文件中通过${{secrets.*}}获取对应的密钥

1662042506481

遇到的问题

1. step执行多行命令

1
2
3
4
- name: Clean install dependencies and build
run: |
npm ci
npm run build

2. 流水线无法切换目录

在流水线里面无法使用cd等shell命令切换目录路径,需要使用working-directory的方式设置工作路径

流水线的初始路径是仓库的根目录

step中通过working-directory指定工作目录,属于step间不可见的,每个step需要单独设置

1
2
3
- name: Clean temp directory
run: rm -rf *
working-directory: ./temp

若想要同job里的step都在同一个工作目录下,则可以在job中通过defaults.run.working-directory

1
2
3
4
5
6
7
jobs:
job1:
runs-on: ubuntu-latest
defaults:
run:
shell: bash
working-directory: scripts

3. NPM version不可回退

NPM规定每次发包必须保证版本号比上次的大

具体版本规则参照: NPM发包版本号规范

这里我通过在版本号后追加Git的commitID(前6位)解决

最终版本号样例:1.0.0-e915db

通过流水线使用github上下文对象将commitID设置为环境变量(COMMIT_ID),shell脚本通过${COMMIT_ID:0:6}即可获取到6位commitID了

1
2
3
4
5
6
- name: Publish
# if: github.ref_name == 'master'
run: ./build.sh publish
env:
COMMIT_ID: ${{ github.sha }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

通过github.sha可获取到提交ID,将其设置到COMMIT_ID的环境变量中

shell脚本中即可引用到该变量

1
sed -i 's/"version": "1.0.0"/"version": "1.0.0-'"${COMMIT_ID:0:6}"'"/' package.json

使用sed命令搜索package.json中的version属性,将其替换即可

4. Shell脚本没有执行权限

上库前执行git update-index --chmod=+x xxx.sh添加执行权限后再上库

或者在流水线执行时先执行chmod +x xxx.sh的命令赋予执行权限