Github Actions 转换图片和构建博客

Github Actions 转换图片和构建博客

最后修改于 2022-3-18 ⋅ 共 1.7k 字 ⋅ 4分钟 / #Tutorial / #博客, #Action, #自动构建, #CI/CD

构想 #

本文使用 Github Action 来实现本地上传图片后自动在云端处理,弃用原来的 picgo,顺便将博客构建过程也移到云端。TinyPNG 是一个无损转换 PNG 图片的网站,通过将图片颜色索引化可以大大降低大小。网站提供转换 API 可供使用。以下是本博客使用的三个 repos 和自动化操作流程。

repo作用
blogData博客文章源文件
cdn存储引用的图片和其他文件
robust-wqjsdelivr 代理的公共仓库
user.github.io从源文件生成的博客

另外,利用 vercel 提供的后端服务(动态内容可以使用 serverless 功能),将其作为一个 Github repo 的 cdn 来提升访问速度(vercel 在国内依旧可以保持连接)。

旧方案 #

图片文件通过 picgo 上传,博客由本地脚本搭建到 blogData 下的文件夹 ./public/ 内(该文件夹是 blogData 的子模块 user.githun.io)。每次需要构建时由脚本先生成博客文件,作为子模块同步完后再同步源文件。

新方案 #

通过 git 命令或者网页上传原始图片,通过 Github Action 处理并替换,同步到公共用户的 repo中。博客只需要同步源文件,构建和部署都在 Github Action 中完成。

流程图 #

  1. 重命名返回可插入文章的链接并上传图片

    graph LR a[souce rcp.sh old.PNG]-->b[复制为
    cdn/img/2019..0214.png]-->d[commit & push]-->e[Actions/tinify.yml
    push 触发同步到 robust-wq] a-->c["返回![](https://jsdelivr/xx)"]

  2. 构建博客

    graph LR f[source UPDATE
    上传源文件至私有库]-->g[Actions/gh.yaml
    push 触发生成博客]-->i[部署至 user.github.io]

本地脚本 #

图片命名为时间戳 #

通过 git clone https://github.com/./cdn 将 cdn 文件夹放置在本地目录(因为如果是子模块的话需要额外设置,所以不建议直接放在 blogData 这个 repo 内作为子模块使用),此处放置在 ~/cdn
在该目录内添加一个名为 rcp 的脚本。这个脚本将按照输入的图片地址参数将图片复制到cdn/img/文件夹中,并将图片按照时间改名为20210302xx.png

1
2
3
4
5
6
> chmod +x rcp
> ./rcp ~/download/old.png
# 先返回用于插入文章的链接,然后上传
![](https://cdn.jsdelivr.net/gh/robust-wq/cdn/img/2021xx.png)
...
DONE

rcp.sh内容:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/sh
if [ $# != 1 ] ; then
	echo "USAGE: $0 [Image file path]"
	echo " e.g.: $0 ~/download/rad.png"
	exit 1;
fi
filename="$1"
# filename="`readlink -m $1`"
nfname="`date '+%Y%m%d%H%M%S'``echo .${filename##*.}|tr [:upper:] [:lower:]`"
cd "$(dirname "$0")"
echo "![](https://cdn.jsdelivr.net/gh/robust-wq/cdn/img/$nfname)"
echo 
echo PULLING...
git pull
cp "$filename" "./img/$nfname"
git add -A
git commit -m "Add $nfname"
echo PUSHING...
git push
echo DONE

Github Action #

Actions 整理 #

Repo脚本名包含 Action说明
cdntinify.ymlcheckout, tinify, copycat压缩图片并替换,完成后复制到其他 repo
blogDatagh.ymlcheckout, blog, gh-pages生成博客并发布到 github.io
  1. actions/checkout@v2: 获得 git 内容
  2. namoscato/action-tinify@v1: 用 TinyPNG/JPG 压缩图片
  3. andstor/copycat-action@v3: 将指定文件同步至 robust-wq 中
  4. peaceiris/actions-gh-pages@v3: 发布博客

图片处理 Actions #

脚本所在 repo: ./cdn
push 触发 Actions 脚本,压缩此次 commit 的图片并替换上传的图片,同步到 cdn 这个 repo。完成后将该 repo 下除 .github/ 以外的文件同步至 robust-wq 中。
点击 repo 页面中的Actions选项,创建.github/workflows/tinify.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
name: tinify-copy
on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]
  workflow_dispatch:
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: check last changed files
        run: git diff-tree --no-commit-id --name-only -r ${{ github.sha }}
      - uses: namoscato/action-tinify@v1
        with:
          api_key: ${{ secrets.TINIFY_API_KEY }}
          github_token: ${{ secrets.GITHUB_TOKEN }}      
      - name: repo-sync
        uses: andstor/copycat-action@v3
        with:
          username: github-actions[bot]
          email: github-actions[bot]@users.noreply.github.com
          commit_message: beep..reCHaRgeD
          clean: true
          personal_token: ${{ secrets.DST_REPO_TOKEN }}
          exclude: .github/*
          src_path: ./
          src_branch: main
          dst_path: /
          dst_branch: main
          dst_owner: robust-wq
          dst_repo_name: cdn

打开Settings/Secrets,点击New repository secret,添加tinify_api_key(来自 Tinify API)repo_token(在个人设置Personal access tokens获取),此处无需再添加后一项了,Action组件自动会读取。进入 robust-wq 账号,获取个人凭证并作为DST_REPO_TOKEN填入Secrets注意:创建的 secret 不能以 github 开头

自动构建站点 #

脚本所在 repo: blogData
.github/workflows下创建gh.yaml,需要替换 ./github.io

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
name: github pages

on:
  push:
    branches:
      [main, master]  # Set a branch to deploy

jobs:
  deploy:
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/checkout@v2
        with:
          submodules: true  # Fetch blog themes (true OR recursive)
          fetch-depth: 0    # Fetch all history for .GitInfo and .Lastmod
...
      - name: Deploy
        uses: peaceiris/actions-gh-pages@v3
        with:
          personal_token: ${{ secrets.PERSONAL_TOKEN }}
          external_repository: ./github.io
          publish_dir: ./public
          user_name: 'github-actions[bot]'
          user_email: 'github-actions[bot]@users.noreply.github.com'

因为要把页面发布到其他的 repo 中,所以此处不能使用免获取的GITHUB_TOKEN。在个人设置的凭证申请页获取到凭证后,在Secrets中作为PERSONAL_TOKEN填入。

发布博客 #

创建脚本UPDATE,写入:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#!/usr/bin/sh
pwd
if ! pgrep -f ssh-agent; then
  echo -ne '\007'
  eval $(ssh-agent -s)
  ssh-add ~/.ssh/id_rsa
else
  echo ssh-agent is already running..
fi

git add -A &&
git commit -m "`date '+%Y-%m-%d %H:%M:%S'`" &&
git push
echo DONE

总的来讲,如果要在博客中插入图片,进入cdn文件夹,通过 ./rcp "[本地图片地址]" 获取到加速后的链接。需要生成博客,输入source UPDATE

其他 #

原计划是使用 Vercel(类似于 Netlify,但是用的不是 Cloudflare),后来的方案是主站使用 Level CDN 加速,字体文件(中文字体比较大)则和图片一样放到 Github 上的 Repo 里(即本文的 cdn 同步至 robust-wq/),再由 jsdelivr 加速。