对于 Hakyll 这类静态网站构建系统来说,写完的没有写完的网站文章、网站的样式和静态资源等有关的一切都可以方便地使用 Git 进行管理。出于隐私和信息安全方面的考虑,我自建了 Gitea 来管理这个小网站的源码,也自建了 Drone CI 来自动构建和发布网站更新。怎么搭建这两个服务可以参考 这篇文档 和 这篇文档 以及 我的 dockerfiles 仓库 里的 docker-compose 文件,这篇文章将会记录一些官方文档没有涉及到的东西。
为 Hakyll 网站定义 Drone CI 管道
在网站 Git 仓库的根目录下新建包含如下内容的 .drone.yml 文件:
---
kind: pipeline
type: docker
name: default
steps:
- name: build
image: haskell:8.10.7-slim # current lts
commands:
- stack build
- stack exec site build以上就是一个最基础的构建管道定义了,上述管道在执行的时候会调用 Docker Runner 拉取 镜像 并在容器内使用 stack 构建网站。我现在在用 GitHub Pages 托管网站,所以我找来了 gh-pages 插件 来实现使用 CI 发布网站更新。我们需要在 .drone.yml 的 build 这一步下方添加如下内容:
- name: publish
image: plugins/gh-pages
settings:
target_branch: gh-pages
pages_directory: public/
remote_url: https://github.com/zebraNeon/zebraNeon.github.io.git
username: zebraNeon
password:
from_secret: gh_token
when:
event:
- promote
target:
- gh-pages其中 when 对应的值定义了 publish 这一步仅会在项目被 promote 到 gh-pages 时执行。我们可以在 Drone 后台的构建详情页面的右上角找到 promote 按键(我用的这一版后台上这个按钮是在详情菜单里),然后在 target 内填上 gh-pages 就能触发一次带有 build 和 publish 两阶段的构建了。(如果没有这个按钮或者详情菜单之类的,可能是 Drone 后台处于未登录状态。)from_secret: gh_token 表示系统将会在执行构建时从仓库设置的 Secrets 中拿取这一敏感信息的值,详细信息可以参考 这篇文档。
为构建管道添加缓存
Drone CI 没有自带的缓存构建文件功能,需要通过插件来实现。我选择了 Meltwater 开发的缓存插件,这个插件可以将构建文件缓存以模板字符串为键储存到 S3 服务或文件系统中。在这里我自建了 MinIO 这一 S3 兼容的储存服务用来存放构建缓存。由于插件自身限制,我们在创建 MinIO 储存桶时需要为桶指定区域(使用 AWS 代号),不然插件将无法正常工作。将 .drone.yml 中的步骤定义重写为如下内容:
steps:
- name: restore-cache
image: meltwater/drone-cache:dev
environment:
AWS_ACCESS_KEY_ID:
from_secret: drone_cache_access_key
AWS_SECRET_ACCESS_KEY:
from_secret: drone_cache_secret_key
settings:
restore: true
cache_key: '{{ .Repo.Name }}-{{ .Commit.Branch }}'
endpoint: <YOUR-MINIO-HOST>:9000
region: <YOUR-MINIO-REGION>
bucket: <YOUR-MINIO-BUCKET>
path_style: true
mount:
- .stack # i.e. <workspace-path>/.stack
- .stack-work # i.e. <workspace-path>/.stack
- name: build
image: haskell:8.10.7-slim # current lts
environment:
STACK_ROOT: /drone/src/.stack # /drone/src is the default workspace-path
commands:
- stack build
- stack exec site build
- name: rebuild-cache
image: meltwater/drone-cache:dev
environment:
AWS_ACCESS_KEY_ID:
from_secret: drone_cache_access_key
AWS_SECRET_ACCESS_KEY:
from_secret: drone_cache_secret_key
settings:
rebuild: true
cache_key: '{{ .Repo.Name }}-{{ .Commit.Branch }}'
endpoint: <YOUR-MINIO-HOST>:9000
region: <YOUR-MINIO-REGION>
bucket: <YOUR-MINIO-BUCKET>
path_style: true
mount:
- .stack
- .stack-work
- name: publish
image: plugins/gh-pages
settings:
target_branch: gh-pages
pages_directory: public/
remote_url: https://github.com/zebraNeon/zebraNeon.github.io.git
username: zebraNeon
password:
from_secret: gh_token
when:
event:
- promote
target:
- gh-pages可以看到在这里我使用了环境变量指定了 .stack 文件夹的位置,将「仓库名 - 分支名」作为缓存文件的键。cache_key 的具体定义方式可以参考 这段文档。