116 lines
3.4 KiB
YAML
116 lines
3.4 KiB
YAML
name: Create Blog Post
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
title:
|
|
description: "Post title"
|
|
required: true
|
|
type: string
|
|
slug:
|
|
description: "URL slug, for example my-new-post"
|
|
required: true
|
|
type: string
|
|
summary:
|
|
description: "Short summary"
|
|
required: false
|
|
type: string
|
|
tags:
|
|
description: "Comma-separated tags"
|
|
required: false
|
|
type: string
|
|
categories:
|
|
description: "Comma-separated categories"
|
|
required: false
|
|
type: string
|
|
draft:
|
|
description: "Create as draft"
|
|
required: true
|
|
type: boolean
|
|
default: true
|
|
|
|
jobs:
|
|
create-post:
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: write
|
|
steps:
|
|
- name: Checkout source
|
|
uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Generate post file
|
|
env:
|
|
INPUT_TITLE: ${{ inputs.title }}
|
|
INPUT_SLUG: ${{ inputs.slug }}
|
|
INPUT_SUMMARY: ${{ inputs.summary }}
|
|
INPUT_TAGS: ${{ inputs.tags }}
|
|
INPUT_CATEGORIES: ${{ inputs.categories }}
|
|
INPUT_DRAFT: ${{ inputs.draft }}
|
|
run: |
|
|
python3 - <<'PY'
|
|
import os
|
|
import re
|
|
from datetime import datetime, timezone
|
|
from pathlib import Path
|
|
|
|
def split_csv(value: str):
|
|
if not value:
|
|
return []
|
|
return [item.strip() for item in value.split(",") if item.strip()]
|
|
|
|
title = os.environ["INPUT_TITLE"].strip()
|
|
slug = os.environ["INPUT_SLUG"].strip().lower()
|
|
summary = os.environ.get("INPUT_SUMMARY", "").strip()
|
|
draft = os.environ.get("INPUT_DRAFT", "true").strip().lower() == "true"
|
|
tags = split_csv(os.environ.get("INPUT_TAGS", ""))
|
|
categories = split_csv(os.environ.get("INPUT_CATEGORIES", ""))
|
|
|
|
if not title:
|
|
raise SystemExit("Title is required")
|
|
if not re.fullmatch(r"[a-z0-9]+(?:-[a-z0-9]+)*", slug):
|
|
raise SystemExit("Slug must use lowercase letters, numbers, and hyphens only")
|
|
|
|
content_dir = Path("content/posts")
|
|
content_dir.mkdir(parents=True, exist_ok=True)
|
|
target = content_dir / f"{slug}.md"
|
|
if target.exists():
|
|
raise SystemExit(f"Post already exists: {target}")
|
|
|
|
now = datetime.now(timezone.utc).astimezone().replace(microsecond=0).isoformat()
|
|
|
|
def format_array(values):
|
|
if not values:
|
|
return "[]"
|
|
return "[{}]".format(", ".join(f'\"{value}\"' for value in values))
|
|
|
|
escaped_title = title.replace('"', '\\"')
|
|
escaped_summary = summary.replace('"', '\\"')
|
|
|
|
body = f"""++++
|
|
title = \"{escaped_title}\"
|
|
date = {now}
|
|
draft = {\"true\" if draft else \"false\"}
|
|
slug = \"{slug}\"
|
|
summary = \"{escaped_summary}\"
|
|
tags = {format_array(tags)}
|
|
categories = {format_array(categories)}
|
|
++++
|
|
|
|
Write your post here.
|
|
"""
|
|
|
|
target.write_text(body, encoding="utf-8")
|
|
print(target)
|
|
PY
|
|
|
|
- name: Commit new post
|
|
env:
|
|
POST_SLUG: ${{ inputs.slug }}
|
|
run: |
|
|
git config user.name "forgejo-actions"
|
|
git config user.email "forgejo-actions@localhost"
|
|
git add "content/posts/${POST_SLUG}.md"
|
|
git commit -m "Create post: ${POST_SLUG}"
|
|
git push
|