GitHub Actions Automation for Sora 2 Prompt Management¶
This article is a follow-up to the implementation guide
Base article: Sora 2 Prompt Version Control Implementation
Goals¶
- Automate Notion DB registration on Gist commits via GitHub Actions, eliminating manual operations
- Auto-insert prompt diffs as PR comments to reduce review time by 30%
- Ensure production reliability with secrets management and error retry logic
Architecture Overview¶
[GitHub Gist Push]
↓ (webhook trigger)
[GitHub Actions Workflow]
├→ (1) Fetch Gist diff (gh CLI)
├→ (2) Register to Notion API (Python script)
└→ (3) PR diff comment (GitHub API)
[Pull Request]
↓ (opened/synchronize)
[Workflow: PR Comment]
├→ Extract prompt diff
└→ Auto-comment credit prediction table
Implementation Steps¶
Step 1: Secrets Configuration and Repository Setup¶
Register the following secrets in your GitHub repository.
# Register in GitHub Settings → Secrets → Actions
NOTION_TOKEN=secret_xxx
NOTION_DATABASE_ID=abc123
GIST_TOKEN=ghp_xxx # PAT with Gist read permission
Repository structure example:
.github/
workflows/
sync-notion.yml
pr-review.yml
scripts/
sync_gist_to_notion.py
extract_prompt_diff.py
Step 2: Gist→Notion Auto-Sync Workflow¶
Implement workflow to auto-register Gist commits to Notion DB.
name: Sync Gist to Notion
on:
workflow_dispatch:
inputs:
gist_id:
description: 'Gist ID to sync'
required: true
jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: pip install requests tenacity
- name: Sync to Notion
env:
NOTION_TOKEN: ${{ secrets.NOTION_TOKEN }}
DATABASE_ID: ${{ secrets.NOTION_DATABASE_ID }}
GIST_TOKEN: ${{ secrets.GIST_TOKEN }}
GIST_ID: ${{ github.event.inputs.gist_id }}
run: python scripts/sync_gist_to_notion.py
Python Script (scripts/sync_gist_to_notion.py):
import os
import json
import requests
from tenacity import retry, stop_after_attempt, wait_exponential
NOTION_TOKEN = os.environ["NOTION_TOKEN"]
DATABASE_ID = os.environ["DATABASE_ID"]
GIST_ID = os.environ["GIST_ID"]
GIST_TOKEN = os.environ["GIST_TOKEN"]
@retry(stop=stop_after_attempt(3), wait=wait_exponential(min=2, max=10))
def add_to_notion(payload):
url = "https://api.notion.com/v1/pages"
headers = {
"Authorization": f"Bearer {NOTION_TOKEN}",
"Content-Type": "application/json",
"Notion-Version": "2022-06-28"
}
response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()
return response.json()
def fetch_gist():
url = f"https://api.github.com/gists/{GIST_ID}"
headers = {"Authorization": f"token {GIST_TOKEN}"}
response = requests.get(url, headers=headers)
response.raise_for_status()
return response.json()
def main():
gist = fetch_gist()
for filename, file_data in gist["files"].items():
if filename.endswith(".json"):
prompt_data = json.loads(file_data["content"])
payload = {
"parent": {"database_id": DATABASE_ID},
"properties": {
"Name": {"title": [{"text": {"content": prompt_data["id"]}}]},
"Prompt": {"rich_text": [{"text": {"content": prompt_data["prompt"][:2000]}}]},
"Credits": {"number": prompt_data["metadata"]["credits_used"]},
"Success": {"checkbox": prompt_data["metadata"]["success"]},
"Tags": {"multi_select": [{"name": t} for t in prompt_data["metadata"]["tags"]]}
}
}
add_to_notion(payload)
print(f"✅ Synced: {filename}")
if __name__ == "__main__":
main()
Step 3: Auto PR Diff Comment Insertion¶
Extract prompt diffs on PR creation and comment with credit prediction.
name: PR Prompt Review
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Extract prompt diff
id: diff
run: |
git diff origin/main...HEAD -- '*.json' > diff.txt
python scripts/extract_prompt_diff.py diff.txt > comment.md
- name: Post PR comment
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const body = fs.readFileSync('comment.md', 'utf8');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
Diff Extraction Script (scripts/extract_prompt_diff.py):
import sys
import json
import re
def parse_diff(diff_file):
with open(diff_file) as f:
content = f.read()
changes = []
for match in re.finditer(r'-"prompt": "(.*?)"\n\+"prompt": "(.*?)"', content, re.DOTALL):
old, new = match.groups()
changes.append({"old": old[:100], "new": new[:100]})
if not changes:
return "No differences"
table = "| Before | After | Est. Impact |\n|--------|-------|-------------|\n"
for i, ch in enumerate(changes, 1):
credit_impact = "+10" if len(ch["new"]) > len(ch["old"]) else "-5"
table += f"| {ch['old'][:50]}... | {ch['new'][:50]}... | {credit_impact}cr |\n"
return f"## Prompt Diff Review\n\n{table}\n\nEst. Total Impact: {sum([10 if len(c['new'])>len(c['old']) else -5 for c in changes])}cr"
if __name__ == "__main__":
print(parse_diff(sys.argv[1]))
Benchmark: Before/After Automation¶
| Metric | Manual | Automated | Improvement |
|---|---|---|---|
| Notion Registration Time | 5min/item | 30sec/item | 90% reduction |
| Review Prep Time | 15min/PR | 0min (auto) | 100% elimination |
| Sync Error Rate | 12% | 0.5% | 96% reduction |
| Monthly Effort Saved | - | 8 hours | - |
Test conditions: 3-person team, 50 prompt updates/month, 2-month operational data
Failure Patterns and Mitigations¶
| Symptom | Cause | Mitigation |
|---|---|---|
| Frequent Notion API 429 errors | Rate limit exceeded | Implement retry + backoff with tenacity |
| Gist fetch auth errors | Insufficient PAT permissions | Reissue token with gist scope |
| Empty PR diff comment failure | Non-JSON file changes detected | Add -- '*.json' filter to git diff |
| Unexpected workflow failures | Misconfigured Secrets | Pre-test with workflow_dispatch |
Automation & Extension Ideas¶
- Slack Integration: Notify diff summary to Slack on workflow completion
- ML-based Credit Prediction: Train ML model on historical data for improved accuracy
- Periodic Backups: Weekly JSON export of Notion DB to S3
- Multi-repo Support: Monitor Gists across entire organization
- Approval Flow: Require manual approval for high-cost prompts before Notion registration
Next Steps¶
- GitHub Actions Complete Guide - Detailed workflow syntax
- Notion API Retry Best Practices - Official error handling recommendations
- GitHub CLI Gist Commands - Detailed Gist operations