feat: flyt sitet fra Astro til Zola
Samme indhold, URL'er og udseende, bygget af en enkelt zola-binær og Tailwind standalone-CLI uden Node. Kanonisk domæne er asger.weirsoe.dk. Blogindlæg ligger som page bundles med frontmatter Zola forstår, så de gamle stempler er ugyldige, indtil scripts/omstempl.py er kørt med PUBLISH_KEY. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
7e13068dd2
commit
e58a11c2b4
Executable
+103
@@ -0,0 +1,103 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Stempler de udgivne indlæg om efter flytningen fra src/content/blog/<slug>.md til
|
||||
content/blog/<slug>/index.md. Stien og frontmatter indgår i stemplet, så de gamle er ugyldige.
|
||||
|
||||
Kør på zola-branchen, med master stadig på Astro-versionen:
|
||||
|
||||
PUBLISH_KEY=<hex> python3 scripts/omstempl.py [--fra master]
|
||||
PUBLISH_KEY=<hex> python3 scripts/verify-approvals.py
|
||||
git commit -am "blog: stempl indlæg om efter flytning til Zola"
|
||||
|
||||
Scriptet underskriver kun det der allerede var godkendt. For hvert indlæg tjekker det at
|
||||
det gamle stempel er gyldigt, og at den nye fil er præcis den gamle i nyt format. Fejler
|
||||
ét indlæg, skrives der intet.
|
||||
"""
|
||||
import argparse
|
||||
import hashlib
|
||||
import hmac
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
from godkendelse import BLOG, assets_for, read_text, sign, stamp_of # noqa: E402
|
||||
|
||||
OLD = "src/content/blog"
|
||||
|
||||
|
||||
def git(*args, binary=False):
|
||||
return subprocess.run(["git", *args], check=True, capture_output=True, text=not binary).stdout
|
||||
|
||||
|
||||
def old_sign(key, rel, text, assets):
|
||||
"""Det gamle format: stemplet stod som topniveau-linje og er det eneste der skæres fra."""
|
||||
lines = text.replace("\r\n", "\n").split("\n")
|
||||
end = lines.index("---", 1)
|
||||
lines = [l for i, l in enumerate(lines) if not (0 < i < end and l.startswith("godkendt:"))]
|
||||
tail = "".join(f"\n@asset {p} {h}" for p, h in assets)
|
||||
body = f"{rel}\n" + "\n".join(lines) + tail
|
||||
return "v1:" + hmac.new(key, body.encode(), hashlib.sha256).hexdigest()
|
||||
|
||||
|
||||
def migrated(text, stamp):
|
||||
"""Den gamle fil i det nye format: tags under taxonomies, stemplet under extra."""
|
||||
lines = text.split("\n")
|
||||
end = lines.index("---", 1)
|
||||
head = []
|
||||
for l in lines[1:end]:
|
||||
if l.startswith("godkendt:"):
|
||||
continue
|
||||
head += ["taxonomies:", " " + l] if l.startswith("tags:") else [l]
|
||||
return "\n".join(["---", *head, "extra:", f' godkendt: "{stamp}"', *lines[end:]])
|
||||
|
||||
|
||||
def old_assets(ref, slug):
|
||||
out = git("ls-tree", "--name-only", ref, f"{OLD}/{slug}/").split()
|
||||
return sorted((p, hashlib.sha256(git("show", f"{ref}:{p}", binary=True)).hexdigest()) for p in out)
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||
ap.add_argument("--fra", default="master", help="ref med de gamle, godkendte indlæg")
|
||||
args = ap.parse_args()
|
||||
if not os.environ.get("PUBLISH_KEY"):
|
||||
sys.exit("PUBLISH_KEY mangler.")
|
||||
key = bytes.fromhex(os.environ["PUBLISH_KEY"])
|
||||
|
||||
slugs = sorted(n for n in os.listdir(BLOG) if os.path.isdir(f"{BLOG}/{n}"))
|
||||
new, errors = {}, []
|
||||
for slug in slugs:
|
||||
rel = f"{BLOG}/{slug}/index.md"
|
||||
old_rel = f"{OLD}/{slug}.md"
|
||||
try:
|
||||
old = git("show", f"{args.fra}:{old_rel}")
|
||||
except subprocess.CalledProcessError:
|
||||
errors.append(f"{rel}: findes ikke i {args.fra} som {old_rel}; kun godkendelsesflowet må stemple nyt")
|
||||
continue
|
||||
text = read_text(rel)
|
||||
stamp_gl, draft = stamp_of(old)
|
||||
o_assets = old_assets(args.fra, slug)
|
||||
n_assets = assets_for(slug)
|
||||
if draft or not stamp_gl or not hmac.compare_digest(stamp_gl, old_sign(key, old_rel, old, o_assets)):
|
||||
errors.append(f"{old_rel}: det gamle stempel er ikke gyldigt med denne nøgle")
|
||||
continue
|
||||
if text != migrated(old, stamp_of(text)[0]):
|
||||
errors.append(f"{rel}: indholdet er ændret i forhold til {args.fra}")
|
||||
continue
|
||||
if [h for _, h in o_assets] != [h for _, h in n_assets]:
|
||||
errors.append(f"{rel}: billederne er ændret i forhold til {args.fra}")
|
||||
continue
|
||||
new[rel] = migrated(old, sign(key, rel, text, n_assets))
|
||||
if errors:
|
||||
print("\n".join(f"✗ {e}" for e in errors), file=sys.stderr)
|
||||
sys.exit(f"\n{len(errors)} fejl. Intet er skrevet.")
|
||||
for rel, text in new.items():
|
||||
with open(rel, "w", encoding="utf-8", newline="") as f:
|
||||
f.write(text)
|
||||
print(f"✓ {rel}")
|
||||
print(f"\n{len(new)} indlæg stemplet om. Kør scripts/verify-approvals.py og commit.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user