Files
blog/scripts/add_draft_to_hidden.py
T
zqlit 33d54453d7
Deploy to Production / pre-check (push) Successful in 29s
Deploy to Production / build (push) Failing after 23m24s
Deploy to Production / deploy-edgeone (push) Skipped
Deploy to Production / deploy-upyun (push) Skipped
Deploy to Production / finalize (push) Skipped
Deploy to Production / notify-failure (push) Successful in 4s
fix(ci): 用 Python 重写 pre-build 脚本,替换 PowerShell 依赖
Gitea 自建 runner 镜像不含 PowerShell,导致 Run Pre-Build Scripts
以 exitcode 127 失败。改用 Python 3(GitHub/Gitea runner 均预装),
跨平台通用,迁回 GitHub 无需改回。
2026-09-30 22:50:43 +08:00

111 lines
3.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
将所有包含 'status: hidden' 的文章标记为草稿 (draft: true),并清理冲突的设置。
原 PowerShell 版本:scripts/add_draft_to_hidden.ps1
改写原因:Gitea 自建 runner 镜像不含 pwsh,改用 Python 3(GitHub/Gitea 均自带)。
对每篇 content/posts 下的 .md:
1. 若 frontmatter 含 status: hidden
a. draft: false -> draft: true
b. 注释掉冲突的 status: public
c. 若无 draft: true 则在 status: hidden 行后补一行
2. 安全检查:新内容非空、且长度不低于原内容的 90%,否则跳过保存
3. 以 UTF-8(无 BOM)写回
"""
import os
import re
import sys
POSTS_PATH = "content/posts"
# 与原脚本保持一致的正则(多行模式)
RE_STATUS_HIDDEN = re.compile(r'^status:\s*("hidden"|hidden)', re.M)
RE_DRAFT_FALSE = re.compile(r'^draft:\s*false', re.M)
RE_STATUS_PUBLIC = re.compile(r'^status:\s*("public"|public)', re.M)
RE_DRAFT_TRUE = re.compile(r'^draft:\s*true', re.M)
RE_STATUS_HIDDEN_LINE = re.compile(r'^(status:\s*("hidden"|hidden).*$)', re.M)
def main() -> int:
if not os.path.isdir(POSTS_PATH):
print(f"Path not found: {POSTS_PATH}", file=sys.stderr)
return 1
md_files = []
for root, _dirs, files in os.walk(POSTS_PATH):
for name in files:
if name.endswith(".md"):
md_files.append(os.path.join(root, name))
md_files.sort()
count = 0
print("Starting scan for hidden posts cleanup...")
for path in md_files:
with open(path, "r", encoding="utf-8") as f:
content = f.read()
if not content:
print(f" Skipping empty file: {path}")
continue
# 仅处理含 status: hidden 的文件(与原脚本一致,仅匹配 frontmatter 行首)
if not RE_STATUS_HIDDEN.search(content):
continue
modified = False
new_content = content
# 1. draft: false -> draft: true
if RE_DRAFT_FALSE.search(new_content):
new_content = RE_DRAFT_FALSE.sub("draft: true", new_content)
modified = True
print(f" Fixed 'draft: false' in {path}")
# 2. 注释掉 status: public
if RE_STATUS_PUBLIC.search(new_content):
new_content = RE_STATUS_PUBLIC.sub(
r"# \g<0> # Auto-hidden by script", new_content
)
modified = True
print(f" Commented out 'status: public' in {path}")
# 3. 确保存在 draft: true
if not RE_DRAFT_TRUE.search(new_content):
new_content = RE_STATUS_HIDDEN_LINE.sub(
lambda m: f"{m.group(1)}\ndraft: true", new_content
)
modified = True
print(f" Added 'draft: true' to {path}")
if modified:
# 安全检查 1:新内容非空
if not new_content:
print(
f"CRITICAL: New content is empty for {path}. Skipping save.",
file=sys.stderr,
)
continue
# 安全检查 2:长度不应异常缩小(>10%)
if len(new_content) < len(content) * 0.9:
print(
f"CRITICAL: Suspicious size drop for {path}. Skipping save.",
file=sys.stderr,
)
continue
with open(path, "w", encoding="utf-8", newline="") as f:
f.write(new_content)
print(f" -> Saved changes to {path}")
count += 1
print(f"Completed. Updated {count} files.")
return 0
if __name__ == "__main__":
sys.exit(main())