try with cc

This commit is contained in:
自由的世界人 2025-09-05 19:28:05 +08:00
parent c7e64b2d55
commit ecbe8d433a
2 changed files with 21 additions and 250 deletions

View File

@ -1,57 +1,36 @@
name: GitHub Issue Translator
env:
API_KEY: ${{ secrets.TRANSLATE_API_KEY}}
MODEL: ${{ vars.MODEL || 'deepseek/deepseek-v3.1'}}
BASE_URL: ${{ vars.BASE_URL || 'https://api.ppinfra.com/openai'}}
name: Use Claude To Translate
on:
issues:
types: [opened, edited]
issue_comment:
types: [created, edited]
discussion:
types: [created, edited]
discussion_comment:
types: [created, edited]
pull_request_target:
types: [opened, edited]
pull_request_review_comment:
types: [created, edited]
workflow_dispatch:
jobs:
translate:
claude-response:
if: |
(github.event_name == 'issue_comment')||(github.event_name == 'issues')
runs-on: ubuntu-latest
if: github.repository == 'CherryHQ/cherry-studio'
name: Auto Translate GitHub Content
permissions:
issues: write
discussions: write
pull-requests: write
contents: read
pull-requests: read
issues: read
id-token: write
actions: read # Required for Claude to read CI results on PRs
steps:
- name: 🐈‍⬛ Checkout
uses: actions/checkout@v5
- name: 📦 Setting Node.js
uses: actions/setup-node@v4
- name: Checkout repository
uses: actions/checkout@v4
with:
node-version: 20
fetch-depth: 1
- name: 📦 Install translation dependencies
run: |
mkdir -p /tmp/translation-deps
cd /tmp/translation-deps
echo '{"dependencies": {"openai": "^5.12.2", "@octokit/rest": "^21.0.0"}}' > package.json
npm install --no-package-lock
echo "NODE_PATH=/tmp/translation-deps/node_modules" >> $GITHUB_ENV
- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
- name: 🌐 Run Translation Script
run: node scripts/github-translator.js
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY: ${{ github.repository }}
GITHUB_EVENT_NAME: ${{ github.event_name }}
GITHUB_CONTEXT: ${{ toJSON(github) }}
# This is an optional setting that allows Claude to read CI results on PRs
additional_permissions: |
actions: read
prompt: "Replace the issue with its English translation and substitute the original language."

View File

@ -1,208 +0,0 @@
const { Octokit } = require('@octokit/rest')
const OpenAI = require('openai')
class GitHubTranslator {
constructor() {
this.octokit = new Octokit({
auth: process.env.GITHUB_TOKEN
})
this.openai = new OpenAI({
apiKey: process.env.API_KEY,
baseURL: process.env.BASE_URL
})
this.model = process.env.MODEL || 'deepseek/deepseek-v3.1'
this.repo = process.env.GITHUB_REPOSITORY.split('/')
this.context = JSON.parse(process.env.GITHUB_CONTEXT)
}
async translateText(text, targetLang = 'English') {
if (!text || this.isAlreadyTranslated(text) || this.isPrimarylyEnglish(text)) {
return null
}
try {
const response = await this.openai.chat.completions.create({
model: this.model,
messages: [
{
role: 'system',
content: `You are a professional translator. Translate the following text to ${targetLang}. Keep the original formatting (markdown, code blocks, links) intact. If the text is already primarily in ${targetLang}, respond with "NO_TRANSLATION_NEEDED".`
},
{
role: 'user',
content: text
}
],
temperature: 0.3
})
const translation = response.choices[0].message.content.trim()
return translation === 'NO_TRANSLATION_NEEDED' ? null : translation
} catch (error) {
console.error('Translation error:', error)
return null
}
}
isAlreadyTranslated(text) {
return (
text.includes('**🌐 Translation**') ||
text.includes('**English Translation**') ||
text.includes('<!-- Translated by GitHub Translator -->')
)
}
isPrimarylyEnglish(text) {
// Simple heuristic: if text contains mostly English characters
const englishChars = text.match(/[a-zA-Z\s]/g) || []
const totalChars = text.replace(/\s/g, '')
return englishChars.length / totalChars.length > 0.7
}
formatTranslation(originalText, translation) {
return `${originalText}
---
**🌐 English Translation:**
${translation}
<!-- Translated by GitHub Translator -->`
}
async handleIssue() {
const issue = this.context.event.issue
if (!issue) return
let updates = {}
// Translate title
if (issue.title) {
const translatedTitle = await this.translateText(issue.title)
if (translatedTitle) {
updates.title = `${issue.title} / ${translatedTitle}`
}
}
// Translate body
if (issue.body) {
const translatedBody = await this.translateText(issue.body)
if (translatedBody) {
updates.body = this.formatTranslation(issue.body, translatedBody)
}
}
// Update issue if we have translations
if (Object.keys(updates).length > 0) {
await this.octokit.issues.update({
owner: this.repo[0],
repo: this.repo[1],
issue_number: issue.number,
...updates
})
console.log(`✅ Translated issue #${issue.number}`)
}
}
async handleComment() {
const comment = this.context.event.comment
if (!comment) return
const translatedBody = await this.translateText(comment.body)
if (translatedBody) {
await this.octokit.issues.updateComment({
owner: this.repo[0],
repo: this.repo[1],
comment_id: comment.id,
body: this.formatTranslation(comment.body, translatedBody)
})
console.log(`✅ Translated comment #${comment.id}`)
}
}
async handlePullRequest() {
const pr = this.context.event.pull_request
if (!pr) return
let updates = {}
// Translate title
if (pr.title) {
const translatedTitle = await this.translateText(pr.title)
if (translatedTitle) {
updates.title = `${pr.title} / ${translatedTitle}`
}
}
// Translate body
if (pr.body) {
const translatedBody = await this.translateText(pr.body)
if (translatedBody) {
updates.body = this.formatTranslation(pr.body, translatedBody)
}
}
// Update PR if we have translations
if (Object.keys(updates).length > 0) {
await this.octokit.pulls.update({
owner: this.repo[0],
repo: this.repo[1],
pull_number: pr.number,
...updates
})
console.log(`✅ Translated PR #${pr.number}`)
}
}
async handleDiscussion() {
// Note: GitHub's GraphQL API would be needed for full discussion support
console.log('Discussion translation not implemented yet')
}
async run() {
try {
const eventName = process.env.GITHUB_EVENT_NAME
console.log(`🌐 Processing ${eventName} event...`)
switch (eventName) {
case 'issues':
await this.handleIssue()
break
case 'issue_comment':
await this.handleComment()
break
case 'pull_request':
case 'pull_request_target':
await this.handlePullRequest()
break
case 'pull_request_review_comment':
await this.handleComment()
break
case 'discussion':
case 'discussion_comment':
await this.handleDiscussion()
break
default:
console.log(`Event ${eventName} not supported`)
}
} catch (error) {
console.error('Translation workflow error:', error)
process.exit(1)
}
}
}
// Run the translator
if (require.main === module) {
const translator = new GitHubTranslator()
translator.run()
}
module.exports = GitHubTranslator