fix contrib system
This commit is contained in:
@@ -285,120 +285,152 @@ export class GitContributionManager {
|
||||
}
|
||||
}
|
||||
|
||||
// Original tool contribution methods (unchanged)
|
||||
|
||||
async submitContribution(data: ContributionData): Promise<GitOperationResult> {
|
||||
const branchName = `tool-${data.type}-${Date.now()}`;
|
||||
private generateToolYAML(tool: any): string {
|
||||
// Clean up the tool object - remove null/undefined values
|
||||
const cleanTool: any = {
|
||||
name: tool.name,
|
||||
type: tool.type,
|
||||
description: tool.description,
|
||||
domains: tool.domains || [],
|
||||
phases: tool.phases || [],
|
||||
skillLevel: tool.skillLevel,
|
||||
url: tool.url
|
||||
};
|
||||
|
||||
// Add optional fields only if they have values
|
||||
if (tool.icon) cleanTool.icon = tool.icon;
|
||||
if (tool.platforms && tool.platforms.length > 0) cleanTool.platforms = tool.platforms;
|
||||
if (tool.license) cleanTool.license = tool.license;
|
||||
if (tool.accessType) cleanTool.accessType = tool.accessType;
|
||||
if (tool.projectUrl) cleanTool.projectUrl = tool.projectUrl;
|
||||
if (tool.knowledgebase) cleanTool.knowledgebase = tool.knowledgebase;
|
||||
if (tool.related_concepts && tool.related_concepts.length > 0) cleanTool.related_concepts = tool.related_concepts;
|
||||
if (tool.tags && tool.tags.length > 0) cleanTool.tags = tool.tags;
|
||||
|
||||
// Generate clean YAML
|
||||
return dump(cleanTool, {
|
||||
lineWidth: -1,
|
||||
noRefs: true,
|
||||
quotingType: '"',
|
||||
forceQuotes: false,
|
||||
indent: 2
|
||||
});
|
||||
}
|
||||
|
||||
async submitContribution(data: ContributionData): Promise<GitOperationResult> {
|
||||
const branchName = `tool-${data.type}-${Date.now()}`;
|
||||
|
||||
try {
|
||||
// Create branch
|
||||
await this.createBranch(branchName);
|
||||
|
||||
// FIXED: Don't modify tools.yaml at all - just create the tool data file
|
||||
const toolYaml = this.generateToolYAML(data.tool);
|
||||
const contributionFileName = `contribution-${data.type}-${data.tool.name.toLowerCase().replace(/[^a-z0-9]/g, '-')}.yaml`;
|
||||
|
||||
// Create contributions directory if it doesn't exist and write the tool data
|
||||
try {
|
||||
// Create branch
|
||||
await this.createBranch(branchName);
|
||||
|
||||
// Load current tools.yaml
|
||||
const toolsYamlPath = 'src/data/tools.yaml';
|
||||
const content = await this.readFile(toolsYamlPath);
|
||||
const yamlData = load(content) as any;
|
||||
|
||||
if (!yamlData.tools) {
|
||||
yamlData.tools = [];
|
||||
}
|
||||
|
||||
// Apply changes
|
||||
if (data.type === 'add') {
|
||||
// Check if tool already exists
|
||||
const existing = yamlData.tools.find((t: any) => t.name === data.tool.name);
|
||||
if (existing) {
|
||||
throw new Error(`Tool "${data.tool.name}" already exists`);
|
||||
}
|
||||
|
||||
yamlData.tools.push(data.tool);
|
||||
} else if (data.type === 'edit') {
|
||||
const index = yamlData.tools.findIndex((t: any) => t.name === data.tool.name);
|
||||
if (index === -1) {
|
||||
throw new Error(`Tool "${data.tool.name}" not found`);
|
||||
}
|
||||
|
||||
yamlData.tools[index] = { ...yamlData.tools[index], ...data.tool };
|
||||
}
|
||||
|
||||
// Sort tools alphabetically
|
||||
yamlData.tools.sort((a: any, b: any) => a.name.localeCompare(b.name));
|
||||
|
||||
// Generate updated YAML
|
||||
const updatedYaml = dump(yamlData, {
|
||||
lineWidth: -1,
|
||||
noRefs: true,
|
||||
quotingType: '"',
|
||||
forceQuotes: false
|
||||
});
|
||||
|
||||
// Write updated file
|
||||
await this.writeFile(toolsYamlPath, updatedYaml);
|
||||
|
||||
// Commit changes
|
||||
const commitMessage = `${data.type === 'add' ? 'Add' : 'Update'} tool: ${data.tool.name}
|
||||
await this.readFile('contributions/.gitkeep');
|
||||
} catch {
|
||||
// Directory doesn't exist, create it
|
||||
await this.writeFile('contributions/.gitkeep', '# Contribution files directory\n');
|
||||
}
|
||||
|
||||
// Write the tool data as a separate file for maintainers to review
|
||||
await this.writeFile(`contributions/${contributionFileName}`, toolYaml);
|
||||
|
||||
// Commit changes
|
||||
const commitMessage = `${data.type === 'add' ? 'Add' : 'Update'} tool: ${data.tool.name}
|
||||
|
||||
Contributed by: ${data.metadata.submitter}
|
||||
Type: ${data.tool.type}
|
||||
${data.metadata.reason ? `Reason: ${data.metadata.reason}` : ''}`;
|
||||
|
||||
await this.commitChanges(commitMessage);
|
||||
|
||||
// Push branch
|
||||
await this.pushBranch(branchName);
|
||||
|
||||
// Create pull request
|
||||
const prUrl = await this.createPullRequest(
|
||||
branchName,
|
||||
`${data.type === 'add' ? 'Add' : 'Update'} tool: ${data.tool.name}`,
|
||||
this.generatePRDescription(data)
|
||||
);
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: `Tool contribution submitted successfully`,
|
||||
prUrl,
|
||||
branchName
|
||||
};
|
||||
|
||||
} catch (error) {
|
||||
// Cleanup on failure
|
||||
try {
|
||||
await this.deleteBranch(branchName);
|
||||
} catch (cleanupError) {
|
||||
console.error('Failed to cleanup branch:', cleanupError);
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
${data.metadata.reason ? `Reason: ${data.metadata.reason}` : ''}
|
||||
|
||||
private generatePRDescription(data: ContributionData): string {
|
||||
This contribution contains the raw tool data for manual review and integration.`;
|
||||
|
||||
await this.commitChanges(commitMessage);
|
||||
|
||||
// Push branch
|
||||
await this.pushBranch(branchName);
|
||||
|
||||
// Create pull request with enhanced description
|
||||
const prUrl = await this.createPullRequest(
|
||||
branchName,
|
||||
`${data.type === 'add' ? 'Add' : 'Update'} tool: ${data.tool.name}`,
|
||||
this.generateEnhancedPRDescription(data, toolYaml)
|
||||
);
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: `Tool contribution submitted successfully`,
|
||||
prUrl,
|
||||
branchName
|
||||
};
|
||||
|
||||
} catch (error) {
|
||||
// Cleanup on failure
|
||||
try {
|
||||
await this.deleteBranch(branchName);
|
||||
} catch (cleanupError) {
|
||||
console.error('Failed to cleanup branch:', cleanupError);
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private generateEnhancedPRDescription(data: ContributionData, toolYaml: string): string {
|
||||
return `## Tool ${data.type === 'add' ? 'Addition' : 'Update'}: ${data.tool.name}
|
||||
|
||||
**Type:** ${data.tool.type}
|
||||
**Submitted by:** ${data.metadata.submitter}
|
||||
**Type:** ${data.tool.type}
|
||||
**Submitted by:** ${data.metadata.submitter}
|
||||
**Action:** ${data.type === 'add' ? 'Add new tool' : 'Update existing tool'}
|
||||
|
||||
### Tool Details
|
||||
- **Description:** ${data.tool.description}
|
||||
- **Domains:** ${data.tool.domains.join(', ')}
|
||||
- **Phases:** ${data.tool.phases.join(', ')}
|
||||
- **Skill Level:** ${data.tool.skillLevel}
|
||||
- **License:** ${data.tool.license || 'Not specified'}
|
||||
- **URL:** ${data.tool.url}
|
||||
### Tool Details
|
||||
- **Name:** ${data.tool.name}
|
||||
- **Description:** ${data.tool.description}
|
||||
- **URL:** ${data.tool.url}
|
||||
- **Skill Level:** ${data.tool.skillLevel}
|
||||
${data.tool.platforms && data.tool.platforms.length > 0 ? `- **Platforms:** ${data.tool.platforms.join(', ')}` : ''}
|
||||
${data.tool.license ? `- **License:** ${data.tool.license}` : ''}
|
||||
${data.tool.accessType ? `- **Access Type:** ${data.tool.accessType}` : ''}
|
||||
${data.tool.projectUrl ? `- **Project URL:** ${data.tool.projectUrl}` : ''}
|
||||
- **Domains:** ${data.tool.domains.join(', ')}
|
||||
- **Phases:** ${data.tool.phases.join(', ')}
|
||||
${data.tool.tags && data.tool.tags.length > 0 ? `- **Tags:** ${data.tool.tags.join(', ')}` : ''}
|
||||
${data.tool.related_concepts && data.tool.related_concepts.length > 0 ? `- **Related Concepts:** ${data.tool.related_concepts.join(', ')}` : ''}
|
||||
|
||||
${data.metadata.reason ? `### Reason for Contribution\n${data.metadata.reason}` : ''}
|
||||
${data.metadata.reason ? `### Reason for Contribution
|
||||
${data.metadata.reason}
|
||||
|
||||
### Review Checklist
|
||||
- [ ] Tool information is accurate and complete
|
||||
- [ ] Description is clear and informative
|
||||
- [ ] Domains and phases are correctly assigned
|
||||
- [ ] Tags are relevant and consistent
|
||||
- [ ] License information is correct
|
||||
- [ ] URLs are valid and accessible
|
||||
` : ''}### Raw Tool Data (Copy & Paste Ready)
|
||||
|
||||
---
|
||||
*This contribution was submitted via the CC24-Hub web interface.*`;
|
||||
\`\`\`yaml
|
||||
${toolYaml}\`\`\`
|
||||
|
||||
### For Maintainers
|
||||
|
||||
**To add this tool to tools.yaml:**
|
||||
1. Copy the YAML data above
|
||||
2. ${data.type === 'add' ? 'Add it to the tools array in the appropriate alphabetical position' : 'Replace the existing tool entry with this updated data'}
|
||||
3. Verify all fields are correct
|
||||
4. Test that the tool displays properly
|
||||
5. Close this PR
|
||||
|
||||
### Review Checklist
|
||||
- [ ] Tool information is accurate and complete
|
||||
- [ ] Description is clear and informative
|
||||
- [ ] Domains and phases are correctly assigned
|
||||
- [ ] Tags are relevant and consistent with existing tools
|
||||
- [ ] License information is correct (for software)
|
||||
- [ ] URLs are valid and accessible
|
||||
- [ ] No duplicate tool entries
|
||||
- [ ] YAML syntax is valid
|
||||
|
||||
---
|
||||
*This contribution was submitted via the CC24-Hub web interface and contains only the raw tool data for manual integration.*`;
|
||||
}
|
||||
|
||||
async checkHealth(): Promise<{healthy: boolean, issues?: string[]}> {
|
||||
|
||||
Reference in New Issue
Block a user