Files
sunnypilot/.github/workflows/sync-docs-discourse.yml
T
Jason Wen c8d543a8fe more
2026-03-12 22:38:21 -04:00

94 lines
3.4 KiB
YAML

# Discourse Docs Sync — one-way push from docs_sp/ Markdown to Discourse API.
#
# WARNING: This workflow is strictly for Discourse API syncing.
# Do NOT add Zensical build steps, GitHub Pages deployment, or any
# static-site generation to this file. Those belong in docs.yaml.
name: Sync Docs to Discourse
on:
push:
# paths:
# - "docs_sp/**"
# - "zensical.toml"
pull_request:
# paths:
# - "docs_sp/**"
# - "zensical.toml"
workflow_dispatch:
jobs:
smoke-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup environment
run: ./tools/op.sh setup
- name: Smoke test - post one doc to Discourse
env:
DISCOURSE_URL: ${{ secrets.DISCOURSE_URL }}
DISCOURSE_API_KEY: ${{ secrets.DISCOURSE_API_KEY }}
DISCOURSE_API_USER: ${{ secrets.DISCOURSE_API_USER }}
DISCOURSE_CATEGORY_MAP: '{"getting-started": 133}'
run: |
uv run --python 3.12 python -c "
import os, sys
sys.path.insert(0, 'docs_sp/tools')
from pathlib import Path
from converter import convert
from discourse_client import DiscourseClient, DiscourseConfig
DOC_PATH = 'getting-started/what-is-sunnypilot.md'
GITHUB_BRANCH = os.environ.get('GITHUB_REF_NAME', 'master')
raw = (Path('docs_sp') / DOC_PATH).read_text()
body = convert(raw, file_path=DOC_PATH)
# Append sync footer
gh_url = f'https://github.com/sunnypilot/sunnypilot/blob/{GITHUB_BRANCH}/docs_sp/{DOC_PATH}'
body = body.rstrip('\n') + f'\n\n---\n<small>This document is version-controlled. Suggest changes [on GitHub]({gh_url}).</small>\n\n<!-- docs-sync-id: {DOC_PATH} -->\n'
# Extract title from front matter or first heading
title = None
for line in raw.splitlines():
s = line.strip()
if s.startswith('title:'):
title = s[len('title:'):].strip().strip('\"').strip(\"'\")
break
if s.startswith('# '):
title = s[2:].strip()
break
title = f'{title or \"What is sunnypilot?\"} - sunnypilot Docs'
print(f'Title: {title}')
print(f'Body: {len(body)} chars')
config = DiscourseConfig.from_env()
client = DiscourseClient(config)
category_id = config.category_id_for(DOC_PATH)
print(f'Category ID: {category_id}')
existing = client.find_topic_by_sync_id(DOC_PATH)
if existing is not None:
topic_id = existing['id']
post_id = client.first_post_id(topic_id)
if post_id is None:
print(f'ERROR: No first post for topic {topic_id}')
sys.exit(1)
result = client.update_post(post_id, body, edit_reason='CI smoke test')
if result is None:
print('ERROR: Failed to update post')
sys.exit(1)
print(f'Updated: {config.base_url}/t/{topic_id}')
else:
result = client.create_topic(title=title, raw=body, category_id=category_id, tags=['docs-auto-sync'])
if result is None:
print('ERROR: Failed to create topic')
sys.exit(1)
print(f'Created: {config.base_url}/t/{result.get(\"topic_id\", \"?\")}')
print('Smoke test passed!')
"