mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-08-23 17:33:50 +08:00
sync
This commit is contained in:
@@ -1,105 +0,0 @@
|
||||
name: 'Post to Discourse'
|
||||
description: 'Posts a message to a Discourse topic (existing or new)'
|
||||
|
||||
inputs:
|
||||
discourse-url:
|
||||
description: 'Discourse instance URL (e.g., https://discourse.example.com)'
|
||||
required: true
|
||||
api-key:
|
||||
description: 'Discourse API key'
|
||||
required: true
|
||||
api-username:
|
||||
description: 'Discourse API username'
|
||||
required: true
|
||||
topic-id:
|
||||
description: 'Discourse topic ID to post to (use this OR category-id + title)'
|
||||
required: false
|
||||
category-id:
|
||||
description: 'Category ID for new topic (required if topic-id not provided)'
|
||||
required: false
|
||||
title:
|
||||
description: 'Title for new topic (required if topic-id not provided)'
|
||||
required: false
|
||||
message:
|
||||
description: 'Message content (markdown supported)'
|
||||
required: true
|
||||
|
||||
outputs:
|
||||
post-number:
|
||||
description: 'The post number in the topic'
|
||||
value: ${{ steps.post.outputs.post_number }}
|
||||
post-url:
|
||||
description: 'Direct URL to the post'
|
||||
value: ${{ steps.post.outputs.post_url }}
|
||||
topic-id:
|
||||
description: 'The topic ID (useful when creating a new topic)'
|
||||
value: ${{ steps.post.outputs.topic_id }}
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Post to Discourse
|
||||
id: post
|
||||
shell: bash
|
||||
run: |
|
||||
# Validate inputs
|
||||
if [ -z "${{ inputs.topic-id }}" ] && ([ -z "${{ inputs.category-id }}" ] || [ -z "${{ inputs.title }}" ]); then
|
||||
echo "❌ Error: Must provide either topic-id OR both category-id and title"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -n "${{ inputs.topic-id }}" ] && ([ -n "${{ inputs.category-id }}" ] || [ -n "${{ inputs.title }}" ]); then
|
||||
echo "⚠️ Warning: Both topic-id and category-id/title provided. Will post to existing topic."
|
||||
fi
|
||||
|
||||
# Determine if creating new topic or posting to existing
|
||||
if [ -n "${{ inputs.topic-id }}" ]; then
|
||||
echo "📝 Posting to existing topic ID: ${{ inputs.topic-id }}"
|
||||
|
||||
# Create JSON payload for posting to existing topic
|
||||
PAYLOAD=$(jq -n \
|
||||
--arg content '${{ inputs.message }}' \
|
||||
--arg topic_id "${{ inputs.topic-id }}" \
|
||||
'{topic_id: $topic_id, raw: $content}')
|
||||
else
|
||||
echo "✨ Creating new topic: ${{ inputs.title }}"
|
||||
|
||||
# Create JSON payload for new topic
|
||||
PAYLOAD=$(jq -n \
|
||||
--arg content '${{ inputs.message }}' \
|
||||
--arg title "${{ inputs.title }}" \
|
||||
--arg category "${{ inputs.category-id }}" \
|
||||
'{title: $title, category: ($category | tonumber), raw: $content}')
|
||||
fi
|
||||
|
||||
# Post to Discourse
|
||||
RESPONSE=$(curl -s -w "\n%{http_code}" \
|
||||
-X POST "${{ inputs.discourse-url }}/posts.json" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Api-Key: ${{ inputs.api-key }}" \
|
||||
-H "Api-Username: ${{ inputs.api-username }}" \
|
||||
-d "$PAYLOAD")
|
||||
|
||||
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
||||
BODY=$(echo "$RESPONSE" | sed '$d')
|
||||
|
||||
if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then
|
||||
echo "✅ Successfully posted to Discourse!"
|
||||
|
||||
POST_NUMBER=$(echo "$BODY" | jq -r '.post_number // "unknown"')
|
||||
TOPIC_ID=$(echo "$BODY" | jq -r '.topic_id // "${{ inputs.topic-id }}"')
|
||||
POST_URL="${{ inputs.discourse-url }}/t/${TOPIC_ID}/${POST_NUMBER}"
|
||||
|
||||
echo "post_number=${POST_NUMBER}" >> $GITHUB_OUTPUT
|
||||
echo "post_url=${POST_URL}" >> $GITHUB_OUTPUT
|
||||
echo "topic_id=${TOPIC_ID}" >> $GITHUB_OUTPUT
|
||||
|
||||
echo "Topic ID: ${TOPIC_ID}"
|
||||
echo "Post number: ${POST_NUMBER}"
|
||||
echo "URL: ${POST_URL}"
|
||||
else
|
||||
echo "❌ Failed to post to Discourse"
|
||||
echo "HTTP Code: ${HTTP_CODE}"
|
||||
echo "Response: ${BODY}"
|
||||
exit 1
|
||||
fi
|
||||
@@ -0,0 +1,89 @@
|
||||
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: Install uv
|
||||
run: pip install uv
|
||||
|
||||
- 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 }}
|
||||
run: |
|
||||
uv run --python 3.12 -c "
|
||||
import sys
|
||||
sys.path.insert(0, 'docs_sp/tools')
|
||||
from pathlib import Path
|
||||
from converter import convert
|
||||
from discourse_client import DiscourseClient, DiscourseConfig
|
||||
|
||||
DOCS_BASE_URL = 'https://docs.sunnypilot.ai'
|
||||
DOC_PATH = 'getting-started/what-is-sunnypilot.md'
|
||||
|
||||
raw = (Path('docs_sp') / DOC_PATH).read_text()
|
||||
body = convert(raw, file_path=DOC_PATH, docs_base_url=DOCS_BASE_URL)
|
||||
|
||||
# Append sync metadata
|
||||
docs_url = f'{DOCS_BASE_URL}/{DOC_PATH.replace(\".md\", \"/\")}'
|
||||
body = body.rstrip('\n') + f'\n\n---\n:link: [View on docs site]({docs_url})\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)
|
||||
|
||||
cat_id = client.get_category_id()
|
||||
if cat_id is None:
|
||||
print(f'ERROR: Category not found on {config.base_url}')
|
||||
sys.exit(1)
|
||||
|
||||
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=cat_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!')
|
||||
"
|
||||
@@ -1,78 +0,0 @@
|
||||
name: Debug Discourse Posting
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
test-discourse-post:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Post test message to Discourse
|
||||
uses: ./.github/workflows/post-to-discourse
|
||||
with:
|
||||
discourse-url: ${{ vars.DISCOURSE_URL }}
|
||||
api-key: ${{ secrets.DISCOURSE_API_KEY }}
|
||||
api-username: ${{ secrets.DISCOURSE_API_USERNAME }}
|
||||
topic-id: ${{ vars.DISCOURSE_UPDATES_TOPIC_ID }}
|
||||
message: |
|
||||
## 🧪 Test Post from GitHub Actions
|
||||
|
||||
**This is a test post to verify Discourse integration**
|
||||
|
||||
- **Workflow**: ${{ github.workflow }}
|
||||
- **Run Number**: #${{ github.run_number }}
|
||||
- **Branch**: `${{ github.ref_name }}`
|
||||
- **Commit**: ${{ github.sha }}
|
||||
- **Actor**: @${{ github.actor }}
|
||||
- **Timestamp**: ${{ github.event.head_commit.timestamp }}
|
||||
|
||||
---
|
||||
|
||||
### Fake Build Info (for testing)
|
||||
- **Version**: 0.9.8-test
|
||||
- **Build**: #42
|
||||
- **Branch**: release-test
|
||||
|
||||
[View workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
|
||||
|
||||
*This is an automated test message. Drive safe! 🚗💨*
|
||||
|
||||
|
||||
- name: Create topic on Discourse
|
||||
uses: ./.github/workflows/post-to-discourse
|
||||
with:
|
||||
discourse-url: ${{ vars.DISCOURSE_URL }}
|
||||
api-key: ${{ secrets.DISCOURSE_API_KEY }}
|
||||
api-username: ${{ secrets.DISCOURSE_API_USERNAME }}
|
||||
#topic-id: ${{ vars.DISCOURSE_UPDATES_TOPIC_ID }}
|
||||
category-id: 4
|
||||
title: "This is a test of a new topic instead of a reply"
|
||||
message: |
|
||||
## 🧪 Test Post from GitHub Actions
|
||||
|
||||
**This is a test post to verify Discourse integration**
|
||||
|
||||
- **Workflow**: ${{ github.workflow }}
|
||||
- **Run Number**: #${{ github.run_number }}
|
||||
- **Branch**: `${{ github.ref_name }}`
|
||||
- **Commit**: ${{ github.sha }}
|
||||
- **Actor**: @${{ github.actor }}
|
||||
- **Timestamp**: ${{ github.event.head_commit.timestamp }}
|
||||
|
||||
---
|
||||
|
||||
### Fake Build Info (for testing)
|
||||
- **Version**: 0.9.8-test
|
||||
- **Build**: #42
|
||||
- **Branch**: release-test
|
||||
|
||||
[View workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
|
||||
|
||||
*This is an automated test message. Drive safe! 🚗💨*
|
||||
- name: Display results
|
||||
if: always()
|
||||
run: |
|
||||
echo "::notice::Discourse post test completed"
|
||||
echo "Check your Discourse topic to verify the post appeared correctly"
|
||||
Reference in New Issue
Block a user