This commit is contained in:
cghislai 2025-06-08 01:49:05 +02:00
parent c3626542d6
commit 7eea12cce0
3 changed files with 215 additions and 6 deletions

View File

@ -1,6 +1,7 @@
import {CloudEvent, cloudEvent, http} from '@google-cloud/functions-framework';
import { ProcessorService } from './services/processor-service';
import { validateConfig, DRY_RUN_SKIP_GEMINI, DRY_RUN_SKIP_COMMITS } from './config';
import { ProcessResult, HttpResponse, ProjectSummary } from './types';
// Validate configuration on startup
try {
@ -29,8 +30,9 @@ if (isRunningDirectly) {
const processor = new ProcessorService();
console.log('Processing projects...');
const results = await processor.processProjects();
const formattedResults = formatHttpResponse(results);
console.log('Processing completed successfully');
console.log('Results:', JSON.stringify(results, null, 2));
console.log('Results:', JSON.stringify(formattedResults, null, 2));
} catch (error) {
console.error('Error processing projects:', error);
process.exit(1);
@ -38,6 +40,47 @@ if (isRunningDirectly) {
})();
}
/**
* Format process results into a concise HTTP response
* @param results Process results from the processor service
* @returns Formatted HTTP response
*/
export function formatHttpResponse(results: ProcessResult[]): HttpResponse {
// Count successful and failed projects
const projectsSucceeded = results.filter(r => !r.error).length;
const projectsFailed = results.filter(r => !!r.error).length;
// Find main PR URL if any
const mainPullRequestUrl = results.find(r => r.pullRequestUrl)?.pullRequestUrl;
// Format project summaries
const projects: ProjectSummary[] = results.map(result => {
// Count workitems
const workitemsProcessed = result.processedWorkitems.length;
const workitemsSkipped = result.processedWorkitems.filter(w => !w.workitem.isActive).length;
const workitemsUpdated = result.processedWorkitems.filter(w => w.success).length;
return {
name: result.project.name,
success: !result.error,
error: result.error,
workitemsProcessed,
workitemsSkipped,
workitemsUpdated,
pullRequestUrl: result.pullRequestUrl
};
});
return {
success: projectsFailed === 0,
projectsProcessed: results.length,
projectsSucceeded,
projectsFailed,
mainPullRequestUrl,
projects
};
}
/**
* HTTP endpoint for the prompts-to-test-spec function
*/
@ -45,16 +88,19 @@ http('promptToTestSpecHttp', async (req, res): Promise<void> => {
try {
const processor = new ProcessorService();
const results = await processor.processProjects();
const response = formatHttpResponse(results);
res.status(200).json({
success: true,
results
});
res.status(200).json(response);
} catch (error) {
console.error('Error processing projects:', error);
const errorMessage = error instanceof Error ? error.message : String(error);
res.status(500).json({
success: false,
error: error instanceof Error ? error.message : String(error)
projectsProcessed: 0,
projectsSucceeded: 0,
projectsFailed: 1,
projects: [],
error: errorMessage
});
}
});

View File

@ -0,0 +1,137 @@
import { formatHttpResponse } from '../../index';
import { ProcessResult, HttpResponse } from '../../types';
describe('formatHttpResponse', () => {
it('should format process results into a concise HTTP response', () => {
// Create test data
const processResults: ProcessResult[] = [
{
project: {
name: 'project1',
path: '/path/to/project1',
repoHost: 'https://github.com',
repoUrl: 'https://github.com/org/project1.git'
},
processedWorkitems: [
{
workitem: {
name: 'workitem1',
path: '/path/to/workitem1.md',
title: 'Workitem 1',
description: 'Description 1',
isActive: true
},
success: true
},
{
workitem: {
name: 'workitem2',
path: '/path/to/workitem2.md',
title: 'Workitem 2',
description: 'Description 2',
isActive: false
},
success: true
}
],
pullRequestUrl: 'https://github.com/org/project1/pull/123'
},
{
project: {
name: 'project2',
path: '/path/to/project2',
repoHost: 'https://github.com',
repoUrl: 'https://github.com/org/project2.git'
},
processedWorkitems: [
{
workitem: {
name: 'workitem3',
path: '/path/to/workitem3.md',
title: 'Workitem 3',
description: 'Description 3',
isActive: true
},
success: false,
error: 'Failed to process workitem'
}
],
error: 'Failed to process project'
}
];
// Call the function
const response = formatHttpResponse(processResults);
// Verify the response
expect(response).toEqual({
success: false,
projectsProcessed: 2,
projectsSucceeded: 1,
projectsFailed: 1,
mainPullRequestUrl: 'https://github.com/org/project1/pull/123',
projects: [
{
name: 'project1',
success: true,
workitemsProcessed: 2,
workitemsSkipped: 1,
workitemsUpdated: 2,
pullRequestUrl: 'https://github.com/org/project1/pull/123'
},
{
name: 'project2',
success: false,
error: 'Failed to process project',
workitemsProcessed: 1,
workitemsSkipped: 0,
workitemsUpdated: 0
}
]
});
});
it('should handle empty results', () => {
const response = formatHttpResponse([]);
expect(response).toEqual({
success: true,
projectsProcessed: 0,
projectsSucceeded: 0,
projectsFailed: 0,
mainPullRequestUrl: undefined,
projects: []
});
});
it('should handle results with no pull request URLs', () => {
const processResults: ProcessResult[] = [
{
project: {
name: 'project1',
path: '/path/to/project1'
},
processedWorkitems: []
}
];
const response = formatHttpResponse(processResults);
expect(response).toEqual({
success: true,
projectsProcessed: 1,
projectsSucceeded: 1,
projectsFailed: 0,
mainPullRequestUrl: undefined,
projects: [
{
name: 'project1',
success: true,
workitemsProcessed: 0,
workitemsSkipped: 0,
workitemsUpdated: 0
}
]
});
});
});

View File

@ -38,3 +38,29 @@ export interface ProcessResult {
pullRequestUrl?: string;
error?: string;
}
/**
* HTTP response format for the API
*/
export interface HttpResponse {
success: boolean;
projectsProcessed: number;
projectsSucceeded: number;
projectsFailed: number;
mainPullRequestUrl?: string;
projects: ProjectSummary[];
error?: string;
}
/**
* Summary of a project's processing results
*/
export interface ProjectSummary {
name: string;
success: boolean;
error?: string;
workitemsProcessed: number;
workitemsSkipped: number;
workitemsUpdated: number;
pullRequestUrl?: string;
}