mirror of
https://github.com/lobehub/lobehub.git
synced 2026-03-26 13:19:34 +07:00
257 lines
8.6 KiB
JavaScript
257 lines
8.6 KiB
JavaScript
/**
|
|
* 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;
|
|
}
|
|
}
|