chore(backend): run go fmt on entire project to fix formatting #669
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: PR Template Suggester | |
| on: | |
| pull_request: | |
| types: [opened, edited, synchronize] | |
| permissions: | |
| pull-requests: write | |
| issues: write | |
| contents: read | |
| jobs: | |
| suggest-template: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Analyze PR files and auto-apply template | |
| uses: actions/github-script@v7 | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| script: | | |
| const { data: files } = await github.rest.pulls.listFiles({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: context.issue.number, | |
| }); | |
| let goFiles = 0, jsFiles = 0, tsFiles = 0, mdFiles = 0, otherFiles = 0; | |
| for (const file of files) { | |
| const filename = file.filename.toLowerCase(); | |
| if (filename.endsWith('.go')) goFiles++; | |
| else if (filename.endsWith('.js') || filename.endsWith('.jsx')) jsFiles++; | |
| else if (filename.endsWith('.ts') || filename.endsWith('.tsx') || filename.endsWith('.vue')) tsFiles++; | |
| else if (filename.endsWith('.md')) mdFiles++; | |
| else otherFiles++; | |
| } | |
| const totalFiles = goFiles + jsFiles + tsFiles + mdFiles + otherFiles; | |
| if (totalFiles === 0) { console.log('No files changed'); return; } | |
| let suggestedTemplate = null, templateEmoji = '', templateLabel = ''; | |
| if (goFiles / totalFiles > 0.5) { | |
| suggestedTemplate = 'backend'; templateEmoji = '🔧'; templateLabel = 'backend'; | |
| } else if ((jsFiles + tsFiles) / totalFiles > 0.5) { | |
| suggestedTemplate = 'frontend'; templateEmoji = '🎨'; templateLabel = 'frontend'; | |
| } else if (mdFiles / totalFiles > 0.7) { | |
| suggestedTemplate = 'docs'; templateEmoji = '📝'; templateLabel = 'documentation'; | |
| } | |
| const { data: pr } = await github.rest.pulls.get({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: context.issue.number, | |
| }); | |
| const prBody = pr.body || ''; | |
| const usesBackendTemplate = prBody.includes('Pull Request - Backend'); | |
| const usesFrontendTemplate = prBody.includes('Pull Request - Frontend'); | |
| const usesDocsTemplate = prBody.includes('Pull Request - Documentation'); | |
| const usesGeneralTemplate = prBody.includes('Pull Request - General'); | |
| const usingDefaultTemplate = !usesBackendTemplate && !usesFrontendTemplate && !usesDocsTemplate && !usesGeneralTemplate; | |
| if (templateLabel) { | |
| try { | |
| await github.rest.issues.addLabels({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| labels: [templateLabel] | |
| }); | |
| console.log('Added label: ' + templateLabel); | |
| } catch (error) { | |
| console.log('Label might not exist, skipping...'); | |
| } | |
| } | |
| function isPRBodyEmpty(body) { | |
| if (!body || body.trim().length < 100) return true; | |
| const hasEmptyDescription = body.includes('**English:**') && body.match(/\*\*English:\*\*\s*\n\s*\n\s*\n/); | |
| const hasEmptyChanges = body.includes('具体变更') && body.match(/\*\*中文:\*\*\s*\n\s*-\s*\n\s*-\s*\n/); | |
| if (hasEmptyDescription || hasEmptyChanges) return true; | |
| const descMatch = body.match(/\*\*English:\*\*[||]\s*\*\*中文:\*\*\s*\n\s*(.+)/); | |
| if (!descMatch || descMatch[1].trim().length < 10) return true; | |
| return false; | |
| } | |
| if (suggestedTemplate && usingDefaultTemplate) { | |
| const shouldAutoApply = isPRBodyEmpty(prBody); | |
| const templatePath = '.github/PULL_REQUEST_TEMPLATE/' + suggestedTemplate + '.md'; | |
| if (shouldAutoApply) { | |
| try { | |
| const { data: templateFile } = await github.rest.repos.getContent({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| path: templatePath, | |
| ref: context.payload.pull_request.head.ref | |
| }); | |
| const templateContent = Buffer.from(templateFile.content, 'base64').toString('utf-8'); | |
| await github.rest.pulls.update({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: context.issue.number, | |
| body: templateContent | |
| }); | |
| console.log('Auto-applied ' + suggestedTemplate + ' template'); | |
| let fileStats = []; | |
| if (goFiles > 0) fileStats.push('- 🔧 Go files: ' + goFiles); | |
| if (jsFiles > 0) fileStats.push('- 🎨 JavaScript files: ' + jsFiles); | |
| if (tsFiles > 0) fileStats.push('- 🎨 TypeScript files: ' + tsFiles); | |
| if (mdFiles > 0) fileStats.push('- 📝 Markdown files: ' + mdFiles); | |
| if (otherFiles > 0) fileStats.push('- 📦 Other files: ' + otherFiles); | |
| const fileStatsText = fileStats.join('\n'); | |
| const notifyComment = '## ' + templateEmoji + ' 已自动应用专用模板 | Auto-Applied Template\n\n' + | |
| '检测到您的PR主要包含 **' + suggestedTemplate + '** 相关的变更,系统已自动为您应用相应的模板。\n\n' + | |
| 'Detected that your PR primarily contains **' + suggestedTemplate + '** changes. The appropriate template has been automatically applied.\n\n' + | |
| '**文件统计 | File Statistics**\n' + fileStatsText + '\n\n' + | |
| '**已应用模板 | Applied Template**\n`' + templatePath + '`\n\n' + | |
| '✨ 您现在可以直接在PR描述中填写相关信息了!\n\n' + | |
| '✨ You can now fill in the relevant information in the PR description!'; | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| body: notifyComment | |
| }); | |
| } catch (error) { | |
| console.log('Failed to fetch or apply template: ' + error.message); | |
| const templateUrl = 'https://raw.githubusercontent.com/' + context.repo.owner + '/' + context.repo.repo + '/dev/.github/PULL_REQUEST_TEMPLATE/' + suggestedTemplate + '.md'; | |
| const fallbackComment = '## ' + templateEmoji + ' 建议使用专用模板 | Suggested Template\n\n' + | |
| '您的PR主要包含 **' + suggestedTemplate + '** 相关的变更。\n\n' + | |
| '**推荐模板 | Recommended Template:** `.github/PULL_REQUEST_TEMPLATE/' + suggestedTemplate + '.md`\n\n' + | |
| '**如何使用 | How to use:** [点击查看模板内容](' + templateUrl + ')'; | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| body: fallbackComment | |
| }); | |
| } | |
| } else { | |
| console.log('PR body has content, sending suggestion only'); | |
| let fileStats = []; | |
| if (goFiles > 0) fileStats.push('- 🔧 Go files: ' + goFiles); | |
| if (jsFiles > 0) fileStats.push('- 🎨 JavaScript files: ' + jsFiles); | |
| if (tsFiles > 0) fileStats.push('- 🎨 TypeScript files: ' + tsFiles); | |
| if (mdFiles > 0) fileStats.push('- 📝 Markdown files: ' + mdFiles); | |
| if (otherFiles > 0) fileStats.push('- 📦 Other files: ' + otherFiles); | |
| const fileStatsText = fileStats.join('\n'); | |
| const templateUrl = 'https://raw.githubusercontent.com/' + context.repo.owner + '/' + context.repo.repo + '/dev/.github/PULL_REQUEST_TEMPLATE/' + suggestedTemplate + '.md'; | |
| const comment = '## ' + templateEmoji + ' 建议使用专用模板 | Suggested Template\n\n' + | |
| '您的PR主要包含 **' + suggestedTemplate + '** 相关的变更。我们建议使用更适合的模板以简化填写。\n\n' + | |
| 'Your PR primarily contains **' + suggestedTemplate + '** changes. We suggest using a more suitable template to simplify filling.\n\n' + | |
| '**文件统计 | File Statistics**\n' + fileStatsText + '\n\n' + | |
| '**推荐模板 | Recommended Template**\n```\n.github/PULL_REQUEST_TEMPLATE/' + suggestedTemplate + '.md\n```\n\n' + | |
| '**如何使用 | How to use**\n' + | |
| '1. 编辑PR描述 | Edit PR description\n' + | |
| '2. 复制 [' + suggestedTemplate + ' 模板内容](' + templateUrl + ') | Copy [' + suggestedTemplate + ' template content](' + templateUrl + ')\n' + | |
| '3. 或在创建PR时使用URL参数 | Or use URL parameter when creating PR\n' + | |
| ' `?template=' + suggestedTemplate + '.md`\n\n' + | |
| '_这是一个自动建议,您可以继续使用当前模板。_\n\n' + | |
| '_This is an automated suggestion. You may continue using the current template._'; | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| body: comment | |
| }); | |
| } | |
| } else if (suggestedTemplate && !usingDefaultTemplate) { | |
| console.log('PR already uses a specific template'); | |
| } else { | |
| console.log('No specific template suggestion needed - mixed changes'); | |
| } |