mirror of
https://github.com/linyqh/NarratoAI.git
synced 2025-12-10 18:02:51 +00:00
197 lines
9.1 KiB
YAML
197 lines
9.1 KiB
YAML
name: Discord Release Notification
|
||
|
||
on:
|
||
release:
|
||
types: [published]
|
||
|
||
jobs:
|
||
notify-discord:
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- name: Checkout code
|
||
uses: actions/checkout@v4
|
||
|
||
- name: Set up Python
|
||
uses: actions/setup-python@v4
|
||
with:
|
||
python-version: '3.10'
|
||
|
||
- name: Install dependencies
|
||
run: pip install openai discord-webhook requests
|
||
|
||
- name: Enhance release notes and send to Discord
|
||
env:
|
||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||
OPENAI_BASE_URL: https://api.siliconflow.cn/v1
|
||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||
run: |
|
||
cat > send_discord_notification.py << 'EOF'
|
||
import os
|
||
import sys
|
||
import json
|
||
from openai import OpenAI
|
||
import requests
|
||
from datetime import datetime
|
||
from discord_webhook import DiscordWebhook, DiscordEmbed
|
||
|
||
# 设置OpenAI客户端
|
||
client = OpenAI(
|
||
api_key=os.environ.get("OPENAI_API_KEY"),
|
||
base_url=os.environ.get("OPENAI_BASE_URL")
|
||
)
|
||
|
||
# 获取GitHub release信息
|
||
github_token = os.environ.get("GITHUB_TOKEN")
|
||
repo = os.environ.get("GITHUB_REPOSITORY")
|
||
|
||
# 直接从GitHub API获取最新release
|
||
headers = {"Authorization": f"token {github_token}"}
|
||
response = requests.get(f"https://api.github.com/repos/{repo}/releases/latest", headers=headers)
|
||
|
||
if response.status_code != 200:
|
||
print(f"Error fetching release info: {response.status_code}")
|
||
print(response.text)
|
||
sys.exit(1)
|
||
|
||
release_info = response.json()
|
||
|
||
# 提取需要的信息
|
||
release_notes = release_info.get("body", "无发布说明")
|
||
version = release_info.get("tag_name", "未知版本")
|
||
|
||
# 安全地解析发布日期
|
||
published_at = release_info.get("published_at")
|
||
if published_at:
|
||
try:
|
||
release_date = datetime.strptime(published_at, "%Y-%m-%dT%H:%M:%SZ").strftime("%Y年%m月%d日")
|
||
except ValueError:
|
||
release_date = "未知日期"
|
||
else:
|
||
release_date = "未知日期"
|
||
|
||
# 使用大模型润色发布说明
|
||
try:
|
||
response = client.chat.completions.create(
|
||
model="deepseek-ai/DeepSeek-V3",
|
||
messages=[
|
||
{"role": "system", "content": "你是一个专业的软件发布公告优化助手。请优化以下发布说明,使其更加生动、专业,并明确区分新功能、优化内容、修复内容和移除内容等类别。保持原有信息的完整性,同时增强可读性和专业性。使用中文回复。\n\n重要:Discord不支持复杂的Markdown格式,因此请使用简单的格式化:\n1. 使用**粗体**和*斜体*而不是Markdown标题\n2. 使用简单的列表符号(•)而不是Markdown列表\n3. 避免使用#、##等标题格式\n4. 不要使用表格、代码块等复杂格式\n5. 确保段落之间有空行\n6. 使用简单的分隔符(如 ------)来分隔不同部分"},
|
||
{"role": "user", "content": f"请优化以下版本{version}的发布说明,使其更适合在Discord社区发布。请记住Discord不支持复杂的Markdown格式,所以使用简单的格式化方式:\n\n{release_notes}"}
|
||
],
|
||
temperature=0.7,
|
||
)
|
||
enhanced_notes = response.choices[0].message.content
|
||
print(f"大模型润色后的发布说明: \n{enhanced_notes}")
|
||
except Exception as e:
|
||
print(f"Error calling OpenAI API: {e}")
|
||
enhanced_notes = release_notes # 如果API调用失败,使用原始发布说明
|
||
|
||
# 创建Discord消息
|
||
webhook_url = os.environ.get("DISCORD_WEBHOOK_URL")
|
||
if not webhook_url:
|
||
print("Error: DISCORD_WEBHOOK_URL not set")
|
||
sys.exit(1)
|
||
|
||
webhook = DiscordWebhook(url=webhook_url)
|
||
|
||
# 创建嵌入式消息
|
||
embed = DiscordEmbed(
|
||
title=f"🚀 NarratoAI {version} 发布公告",
|
||
description=f"发布日期: {release_date}",
|
||
color="5865F2" # Discord蓝色
|
||
)
|
||
|
||
# 处理发布说明,确保不超过Discord的字段限制
|
||
# Discord字段值限制为1024个字符
|
||
MAX_FIELD_LENGTH = 1024
|
||
|
||
# 如果内容很短,直接添加
|
||
if enhanced_notes and len(enhanced_notes) <= MAX_FIELD_LENGTH:
|
||
embed.add_embed_field(name="📋 更新内容", value=enhanced_notes)
|
||
elif enhanced_notes:
|
||
# 尝试按段落或明显的分隔符分割内容
|
||
sections = []
|
||
|
||
# 检查是否有明显的新功能、优化、修复等部分
|
||
if "**新增功能**" in enhanced_notes or "**新功能**" in enhanced_notes:
|
||
parts = enhanced_notes.split("**新增功能**", 1)
|
||
if len(parts) > 1:
|
||
intro = parts[0].strip()
|
||
if intro:
|
||
sections.append(("📋 更新概述", intro))
|
||
|
||
rest = "**新增功能**" + parts[1]
|
||
|
||
# 进一步分割剩余部分
|
||
feature_end = -1
|
||
for marker in ["**优化内容**", "**性能优化**", "**修复内容**", "**bug修复**", "**问题修复**"]:
|
||
pos = rest.lower().find(marker.lower())
|
||
if pos != -1 and (feature_end == -1 or pos < feature_end):
|
||
feature_end = pos
|
||
|
||
if feature_end != -1:
|
||
sections.append(("✨ 新增功能", rest[:feature_end].strip()))
|
||
rest = rest[feature_end:]
|
||
else:
|
||
sections.append(("✨ 新增功能", rest.strip()))
|
||
rest = ""
|
||
|
||
# 继续分割剩余部分
|
||
if rest:
|
||
optimize_end = -1
|
||
for marker in ["**修复内容**", "**bug修复**", "**问题修复**"]:
|
||
pos = rest.lower().find(marker.lower())
|
||
if pos != -1 and (optimize_end == -1 or pos < optimize_end):
|
||
optimize_end = pos
|
||
|
||
if optimize_end != -1:
|
||
sections.append(("⚡ 优化内容", rest[:optimize_end].strip()))
|
||
sections.append(("🔧 修复内容", rest[optimize_end:].strip()))
|
||
else:
|
||
sections.append(("⚡ 优化内容", rest.strip()))
|
||
else:
|
||
# 如果没有明显的结构,按长度分割
|
||
chunks = [enhanced_notes[i:i+MAX_FIELD_LENGTH] for i in range(0, len(enhanced_notes), MAX_FIELD_LENGTH)]
|
||
for i, chunk in enumerate(chunks):
|
||
if i == 0:
|
||
sections.append(("📋 更新内容", chunk))
|
||
else:
|
||
sections.append((f"📋 更新内容(续{i})", chunk))
|
||
|
||
# 添加所有部分到embed
|
||
for name, content in sections:
|
||
if len(content) > MAX_FIELD_LENGTH:
|
||
# 如果单个部分仍然过长,进一步分割
|
||
sub_chunks = [content[i:i+MAX_FIELD_LENGTH] for i in range(0, len(content), MAX_FIELD_LENGTH)]
|
||
for i, chunk in enumerate(sub_chunks):
|
||
if i == 0:
|
||
embed.add_embed_field(name=name, value=chunk)
|
||
else:
|
||
embed.add_embed_field(name=f"{name}(续{i})", value=chunk)
|
||
else:
|
||
embed.add_embed_field(name=name, value=content)
|
||
else:
|
||
embed.add_embed_field(name="📋 更新内容", value="无详细更新内容")
|
||
|
||
# 添加下载链接
|
||
html_url = release_info.get("html_url", "")
|
||
if html_url:
|
||
embed.add_embed_field(name="📥 下载链接", value=html_url, inline=False)
|
||
|
||
# 设置页脚
|
||
embed.set_footer(text=f"NarratoAI 团队 • {release_date}")
|
||
embed.set_timestamp()
|
||
|
||
# 添加嵌入式消息到webhook
|
||
webhook.add_embed(embed)
|
||
|
||
# 发送消息
|
||
response = webhook.execute()
|
||
if response:
|
||
print(f"Discord notification sent with status code: {response.status_code}")
|
||
else:
|
||
print("Failed to send Discord notification")
|
||
EOF
|
||
|
||
# 执行脚本
|
||
python send_discord_notification.py |