mirror of
https://github.com/lobehub/lobehub.git
synced 2026-03-27 13:29:15 +07:00
🔧 chore: Update i18n actions (#8142)
This commit is contained in:
256
.github/scripts/create-failure-issue.js
vendored
Normal file
256
.github/scripts/create-failure-issue.js
vendored
Normal file
@@ -0,0 +1,256 @@
|
||||
/**
|
||||
* Create or update GitHub issue when i18n workflow fails
|
||||
* Usage: node create-failure-issue.js
|
||||
*/
|
||||
|
||||
module.exports = async ({ github, context, core }) => {
|
||||
const runUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
|
||||
const timestamp = new Date().toISOString();
|
||||
const date = timestamp.split('T')[0];
|
||||
|
||||
// Get error details from environment variables
|
||||
const errorDetails = {
|
||||
validateEnv: process.env.ERROR_VALIDATE_ENV || '',
|
||||
rebaseAttempt: process.env.ERROR_REBASE_ATTEMPT || '',
|
||||
createBranch: process.env.ERROR_CREATE_BRANCH || '',
|
||||
installDeps: process.env.ERROR_INSTALL_DEPS || '',
|
||||
runI18n: process.env.ERROR_RUN_I18N || '',
|
||||
commitPush: process.env.ERROR_COMMIT_PUSH || '',
|
||||
};
|
||||
|
||||
// Get step conclusions from environment variables
|
||||
const stepStatus = {
|
||||
validateEnv: process.env.STEP_VALIDATE_ENV || 'Not run',
|
||||
checkBranch: process.env.STEP_CHECK_BRANCH || 'Not run',
|
||||
rebaseAttempt: process.env.STEP_REBASE_ATTEMPT || 'Not run',
|
||||
createBranch: process.env.STEP_CREATE_BRANCH || 'Not run',
|
||||
installDeps: process.env.STEP_INSTALL_DEPS || 'Not run',
|
||||
runI18n: process.env.STEP_RUN_I18N || 'Not run',
|
||||
commitPush: process.env.STEP_COMMIT_PUSH || 'Not run',
|
||||
createPr: process.env.STEP_CREATE_PR || 'Not run',
|
||||
};
|
||||
|
||||
// Find the first non-empty error
|
||||
const mainError =
|
||||
Object.values(errorDetails).find((error) => error && error.trim()) || 'Unknown error occurred';
|
||||
|
||||
// Determine error category for better troubleshooting
|
||||
const getErrorCategory = (error) => {
|
||||
if (error.includes('API') || error.includes('authentication')) return 'API/Authentication';
|
||||
if (error.includes('network') || error.includes('timeout')) return 'Network/Connectivity';
|
||||
if (error.includes('dependencies') || error.includes('bun')) return 'Dependencies';
|
||||
if (error.includes('git') || error.includes('branch') || error.includes('rebase'))
|
||||
return 'Git Operations';
|
||||
if (error.includes('permission') || error.includes('token')) return 'Permissions';
|
||||
return 'General';
|
||||
};
|
||||
|
||||
const errorCategory = getErrorCategory(mainError);
|
||||
|
||||
const issueTitle = `🚨 Daily i18n Update Failed - ${date}`;
|
||||
|
||||
const issueBody = `## 🚨 Automated i18n Update Failure
|
||||
|
||||
**Timestamp:** ${timestamp}
|
||||
**Workflow Run:** [#${context.runNumber}](${runUrl})
|
||||
**Repository:** ${context.repo.owner}/${context.repo.repo}
|
||||
**Branch:** ${context.ref}
|
||||
**Commit:** ${context.sha}
|
||||
|
||||
## ❌ Error Details
|
||||
**Primary Error:** ${mainError}
|
||||
**Category:** ${errorCategory}
|
||||
|
||||
## 🔍 Step Status
|
||||
| Step | Status |
|
||||
|------|--------|
|
||||
| Environment Validation | ${stepStatus.validateEnv} |
|
||||
| Branch Check | ${stepStatus.checkBranch} |
|
||||
| Rebase Attempt | ${stepStatus.rebaseAttempt} |
|
||||
| Branch Creation | ${stepStatus.createBranch} |
|
||||
| Dependencies | ${stepStatus.installDeps} |
|
||||
| i18n Update | ${stepStatus.runI18n} |
|
||||
| Git Operations | ${stepStatus.commitPush} |
|
||||
| PR Creation | ${stepStatus.createPr} |
|
||||
|
||||
## 🔧 Environment Info
|
||||
- **Runner OS:** ${process.env.RUNNER_OS || 'Unknown'}
|
||||
- **Bun Version:** ${process.env.BUN_VERSION || 'Default'}
|
||||
- **Workflow:** \`${context.workflow}\`
|
||||
|
||||
## 📋 Debug Information
|
||||
Debug logs have been uploaded as artifacts and will be available for 7 days.
|
||||
|
||||
${getErrorCategoryHelp(errorCategory)}
|
||||
|
||||
## 🛠️ General Troubleshooting Steps
|
||||
1. Check if all required secrets are properly configured
|
||||
2. Verify OpenAI API quota and billing status
|
||||
3. Review the workflow run logs for detailed error messages
|
||||
4. Check if there are any ongoing GitHub API issues
|
||||
5. Manually trigger the workflow to retry
|
||||
|
||||
## 📊 Workflow Statistics
|
||||
- **Run Number:** ${context.runNumber}
|
||||
- **Run ID:** ${context.runId}
|
||||
- **Event:** ${context.eventName}
|
||||
|
||||
---
|
||||
**Auto-generated by:** [\`${context.workflow}\`](${runUrl})
|
||||
**Labels:** automated, bug, i18n, workflow-failure, ${errorCategory.toLowerCase().replace(/[^a-z0-9]/g, '-')}`;
|
||||
|
||||
try {
|
||||
// Search for existing open issues with similar title
|
||||
const existingIssues = await github.rest.issues.listForRepo({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
labels: 'automated,workflow-failure',
|
||||
state: 'open',
|
||||
per_page: 50,
|
||||
});
|
||||
|
||||
const todayPrefix = `🚨 Daily i18n Update Failed - ${date}`;
|
||||
const existingIssue = existingIssues.data.find((issue) => issue.title.startsWith(todayPrefix));
|
||||
|
||||
if (existingIssue) {
|
||||
// Update existing issue with comment
|
||||
const commentBody = `## 🔄 Additional Failure
|
||||
|
||||
**Timestamp:** ${timestamp}
|
||||
**Workflow Run:** [#${context.runNumber}](${runUrl})
|
||||
**Error Category:** ${errorCategory}
|
||||
**Error:** ${mainError}
|
||||
|
||||
Same issue occurred again. Please investigate the recurring problem.
|
||||
|
||||
### Quick Actions
|
||||
- [ ] Check API quotas and billing
|
||||
- [ ] Verify network connectivity
|
||||
- [ ] Review recent changes that might cause conflicts
|
||||
- [ ] Consider manual intervention
|
||||
|
||||
---
|
||||
*This is failure #${(await getFailureCount(github, context, existingIssue.number)) + 1} for today.*`;
|
||||
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: existingIssue.number,
|
||||
body: commentBody,
|
||||
});
|
||||
|
||||
// Add priority label if this is a recurring issue
|
||||
const failureCount = await getFailureCount(github, context, existingIssue.number);
|
||||
if (failureCount >= 2) {
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: existingIssue.number,
|
||||
labels: ['priority-high', 'recurring'],
|
||||
});
|
||||
}
|
||||
|
||||
core.info(`✅ Updated existing issue #${existingIssue.number}`);
|
||||
core.setOutput('issue-number', existingIssue.number);
|
||||
core.setOutput('issue-url', existingIssue.html_url);
|
||||
core.setOutput('action', 'updated');
|
||||
} else {
|
||||
// Create new issue
|
||||
const labels = [
|
||||
'automated',
|
||||
'bug',
|
||||
'i18n',
|
||||
'workflow-failure',
|
||||
errorCategory.toLowerCase().replace(/[^a-z0-9]/g, '-'),
|
||||
];
|
||||
|
||||
const issue = await github.rest.issues.create({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
title: issueTitle,
|
||||
body: issueBody,
|
||||
labels: labels,
|
||||
});
|
||||
|
||||
core.info(`✅ Created new issue #${issue.data.number}`);
|
||||
core.setOutput('issue-number', issue.data.number);
|
||||
core.setOutput('issue-url', issue.data.html_url);
|
||||
core.setOutput('action', 'created');
|
||||
}
|
||||
} catch (error) {
|
||||
core.setFailed(`Failed to create or update issue: ${error.message}`);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get category-specific help text
|
||||
*/
|
||||
function getErrorCategoryHelp(category) {
|
||||
const helpTexts = {
|
||||
'API/Authentication': `
|
||||
### 🔑 API/Authentication Issues
|
||||
- Verify \`OPENAI_API_KEY\` is correctly set and valid
|
||||
- Check if API key has sufficient quota/credits
|
||||
- Ensure \`GH_TOKEN\` has necessary permissions
|
||||
- Test API connectivity manually`,
|
||||
|
||||
'Network/Connectivity': `
|
||||
### 🌐 Network/Connectivity Issues
|
||||
- Check if OpenAI API is experiencing outages
|
||||
- Verify proxy settings if using \`OPENAI_PROXY_URL\`
|
||||
- Retry the workflow as this might be temporary
|
||||
- Check GitHub Actions service status`,
|
||||
|
||||
'Dependencies': `
|
||||
### 📦 Dependencies Issues
|
||||
- Verify \`bun\` version compatibility
|
||||
- Check for package.json changes that might affect dependencies
|
||||
- Clear cache and retry installation
|
||||
- Review recent dependency updates`,
|
||||
|
||||
'Git Operations': `
|
||||
### 🔧 Git Operations Issues
|
||||
- Check for conflicting changes in target branch
|
||||
- Verify repository permissions
|
||||
- Review recent commits that might cause conflicts
|
||||
- Manual branch cleanup might be required`,
|
||||
|
||||
'Permissions': `
|
||||
### 🔐 Permissions Issues
|
||||
- Verify \`GH_TOKEN\` has \`repo\` and \`issues\` permissions
|
||||
- Check if token can create/update PRs and branches
|
||||
- Ensure token hasn't expired
|
||||
- Review repository settings and branch protection rules`,
|
||||
|
||||
'General': `
|
||||
### 🔍 General Issues
|
||||
- Review detailed error logs in workflow run
|
||||
- Check for recent changes in codebase
|
||||
- Verify all environment variables are set
|
||||
- Consider running workflow manually with debug enabled`,
|
||||
};
|
||||
|
||||
return helpTexts[category] || helpTexts['General'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Count how many times this issue has failed today
|
||||
*/
|
||||
async function getFailureCount(github, context, issueNumber) {
|
||||
try {
|
||||
const comments = await github.rest.issues.listComments({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: issueNumber,
|
||||
});
|
||||
|
||||
const today = new Date().toISOString().split('T')[0];
|
||||
return comments.data.filter(
|
||||
(comment) =>
|
||||
comment.body.includes('Additional Failure') && comment.created_at.startsWith(today),
|
||||
).length;
|
||||
} catch (error) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user