编写可靠的自动化构建与原子发布脚本

在部署静态网站时,最危险的操作莫过于直接在生产根目录执行带有 --delete 参数的 rsync。一旦构建损坏或网络在上传中间断开,访问者就会看到残缺不全甚至完全空白的网页。

本文演示一种简单、安全且广泛应用于专业工业界的原子软链接发布模型 (Atomic Symlink Deployment)。

1. 核心发布流程 (Shell)

以下是自动化发布脚本 publish.sh 的关键部分:

#!/usr/bin/env bash
set -euo pipefail

# 1. 严格预检查
./scripts/check.sh

# 2. 生产环境构建
pelican content -s publishconf.py

# 3. 创建带时间戳的版本目录并上传
RELEASE_TAG=$(date +"%Y%m%d%H%M%S")
REMOTE_DIR="/var/www/pelican-blog"

ssh dmit "mkdir -p ${REMOTE_DIR}/releases/${RELEASE_TAG}"
rsync -avz --delete output/ dmit:${REMOTE_DIR}/releases/${RELEASE_TAG}/

# 4. 原子符号链接切换 (Atomic Symlink Switch)
ssh dmit "ln -sfn ${REMOTE_DIR}/releases/${RELEASE_TAG} ${REMOTE_DIR}/current_tmp && \
          mv -Tf ${REMOTE_DIR}/current_tmp ${REMOTE_DIR}/current"

echo "==> 部署成功!当前版本: ${RELEASE_TAG}"

2. 静态死链与草稿校验器 (Python)

为了防止未完成的草稿(Status: draft)或者拼写错误的图片链接泄露到线上,我们在构建前使用检查器进行扫描:

import os
import re
import sys

def verify_markdown_posts(content_dir="content"):
    has_error = False
    for root, _, files in os.walk(content_dir):
        for f in files:
            if not f.endswith(('.md', '.markdown')):
                continue
            path = os.path.join(root, f)
            with open(path, 'r', encoding='utf-8') as fp:
                content = fp.read()

            # 校验必需元数据
            for key in ['Title:', 'Date:', 'Slug:']:
                if not re.search(rf'^{key}', content, re.MULTILINE):
                    print(f"[Error] {path} 缺少必要元数据: {key}")
                    has_error = True

    return not has_error

if __name__ == "__main__":
    if not verify_markdown_posts():
        sys.exit(1)
    print("[OK] 内容元数据校验通过")

3. 前端交互与隔离样式 (CSS)

为了保证代码块在移动端屏幕上不会把整个页面撑爆产生横向滚动条,代码块内部必须显式声明横向自适应滚动:

pre {
    background: var(--nc-bg-2);
    border: 1px solid var(--nc-border);
    border-radius: 6px;
    padding: 1rem 1.2rem;
    overflow-x: auto;
    max-width: 100%;
    line-height: 1.45;
}

code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
}

代码高亮由 Pelican 自带的 Pygments 预渲染生成,无需在客户端运行庞大的 JS 语法解析器,省电且速度极快。


← 返回文章列表