WIP
This commit is contained in:
parent
6172a58166
commit
b207103030
@ -0,0 +1,355 @@
|
|||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
import { ProjectService } from '../project-service';
|
||||||
|
|
||||||
|
// Mock fs and path modules
|
||||||
|
jest.mock('fs');
|
||||||
|
jest.mock('path');
|
||||||
|
|
||||||
|
describe('ProjectService - Log Append Feature', () => {
|
||||||
|
let projectService: ProjectService;
|
||||||
|
const mockTimestamp = '2023-01-01T12:00:00.000Z';
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
projectService = new ProjectService();
|
||||||
|
|
||||||
|
// Reset all mocks
|
||||||
|
jest.resetAllMocks();
|
||||||
|
|
||||||
|
// Mock path.join to return predictable paths
|
||||||
|
(path.join as jest.Mock).mockImplementation((...args) => args.join('/'));
|
||||||
|
|
||||||
|
// Mock Date.toISOString to return a fixed timestamp
|
||||||
|
jest.spyOn(Date.prototype, 'toISOString').mockReturnValue(mockTimestamp);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.restoreAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('updateWorkitemWithImplementationLog', () => {
|
||||||
|
it('should append logs to existing Log section', async () => {
|
||||||
|
const workitemContent = `## Workitem Title
|
||||||
|
|
||||||
|
This is a description of the workitem.
|
||||||
|
|
||||||
|
- [x] Jira: JIRA-123
|
||||||
|
- [ ] Implementation:
|
||||||
|
- [x] Active
|
||||||
|
|
||||||
|
### Log
|
||||||
|
|
||||||
|
Some existing log content.
|
||||||
|
`;
|
||||||
|
|
||||||
|
const workitem = {
|
||||||
|
name: 'workitem',
|
||||||
|
path: 'path/to/workitem.md',
|
||||||
|
title: 'Workitem Title',
|
||||||
|
description: 'This is a description of the workitem.',
|
||||||
|
jiraReference: 'JIRA-123',
|
||||||
|
implementation: '',
|
||||||
|
isActive: true
|
||||||
|
};
|
||||||
|
|
||||||
|
const status = 'created';
|
||||||
|
const files = ['file1.ts', 'file2.ts'];
|
||||||
|
|
||||||
|
// Mock fs.existsSync to return true for workitem file
|
||||||
|
(fs.existsSync as jest.Mock).mockReturnValue(true);
|
||||||
|
|
||||||
|
// Mock fs.readFileSync to return workitem content
|
||||||
|
(fs.readFileSync as jest.Mock).mockReturnValue(workitemContent);
|
||||||
|
|
||||||
|
// Mock fs.writeFileSync to capture the actual output
|
||||||
|
let actualContent = '';
|
||||||
|
(fs.writeFileSync as jest.Mock).mockImplementation((path, content) => {
|
||||||
|
actualContent = content;
|
||||||
|
});
|
||||||
|
|
||||||
|
await projectService.updateWorkitemWithImplementationLog(workitem, status, files);
|
||||||
|
|
||||||
|
// Verify that fs.existsSync and fs.readFileSync were called with the expected arguments
|
||||||
|
expect(fs.existsSync).toHaveBeenCalledWith('path/to/workitem.md');
|
||||||
|
expect(fs.readFileSync).toHaveBeenCalledWith('path/to/workitem.md', 'utf-8');
|
||||||
|
|
||||||
|
// Verify that fs.writeFileSync was called with the path
|
||||||
|
expect(fs.writeFileSync).toHaveBeenCalledWith(
|
||||||
|
'path/to/workitem.md',
|
||||||
|
expect.any(String),
|
||||||
|
'utf-8'
|
||||||
|
);
|
||||||
|
|
||||||
|
// Get the actual content from the mock
|
||||||
|
const actualContentFromMock = (fs.writeFileSync as jest.Mock).mock.calls[0][1];
|
||||||
|
|
||||||
|
// Verify the complete content equality
|
||||||
|
const expectedContent = `## Workitem Title
|
||||||
|
|
||||||
|
This is a description of the workitem.
|
||||||
|
|
||||||
|
- [x] Jira: JIRA-123
|
||||||
|
- [ ] Implementation:
|
||||||
|
- [x] Active
|
||||||
|
|
||||||
|
### Log
|
||||||
|
|
||||||
|
${mockTimestamp} - Workitem has been implemented. Created files:
|
||||||
|
- file1.ts
|
||||||
|
- file2.ts
|
||||||
|
|
||||||
|
|
||||||
|
Some existing log content.
|
||||||
|
`;
|
||||||
|
expect(actualContentFromMock).toEqual(expectedContent);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should add Log section if it does not exist', async () => {
|
||||||
|
const workitemContent = `## Workitem Title
|
||||||
|
|
||||||
|
This is a description of the workitem.
|
||||||
|
|
||||||
|
- [x] Jira: JIRA-123
|
||||||
|
- [ ] Implementation:
|
||||||
|
- [x] Active
|
||||||
|
|
||||||
|
`;
|
||||||
|
|
||||||
|
const workitem = {
|
||||||
|
name: 'workitem',
|
||||||
|
path: 'path/to/workitem.md',
|
||||||
|
title: 'Workitem Title',
|
||||||
|
description: 'This is a description of the workitem.',
|
||||||
|
jiraReference: 'JIRA-123',
|
||||||
|
implementation: '',
|
||||||
|
isActive: true
|
||||||
|
};
|
||||||
|
|
||||||
|
const status = 'updated';
|
||||||
|
const files = ['file1.ts', 'file2.ts'];
|
||||||
|
|
||||||
|
// Mock fs.existsSync to return true for workitem file
|
||||||
|
(fs.existsSync as jest.Mock).mockReturnValue(true);
|
||||||
|
|
||||||
|
// Mock fs.readFileSync to return workitem content
|
||||||
|
(fs.readFileSync as jest.Mock).mockReturnValue(workitemContent);
|
||||||
|
|
||||||
|
// Mock fs.writeFileSync to capture the actual output
|
||||||
|
let actualContent = '';
|
||||||
|
(fs.writeFileSync as jest.Mock).mockImplementation((path, content) => {
|
||||||
|
actualContent = content;
|
||||||
|
});
|
||||||
|
|
||||||
|
await projectService.updateWorkitemWithImplementationLog(workitem, status, files);
|
||||||
|
|
||||||
|
// Verify that fs.existsSync and fs.readFileSync were called with the expected arguments
|
||||||
|
expect(fs.existsSync).toHaveBeenCalledWith('path/to/workitem.md');
|
||||||
|
expect(fs.readFileSync).toHaveBeenCalledWith('path/to/workitem.md', 'utf-8');
|
||||||
|
|
||||||
|
// Verify that fs.writeFileSync was called with the path
|
||||||
|
expect(fs.writeFileSync).toHaveBeenCalledWith(
|
||||||
|
'path/to/workitem.md',
|
||||||
|
expect.any(String),
|
||||||
|
'utf-8'
|
||||||
|
);
|
||||||
|
|
||||||
|
// Get the actual content from the mock
|
||||||
|
const actualContentFromMock = (fs.writeFileSync as jest.Mock).mock.calls[0][1];
|
||||||
|
|
||||||
|
// Verify the complete content equality
|
||||||
|
const expectedContent = `## Workitem Title
|
||||||
|
|
||||||
|
This is a description of the workitem.
|
||||||
|
|
||||||
|
- [x] Jira: JIRA-123
|
||||||
|
- [ ] Implementation:
|
||||||
|
- [x] Active
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Log
|
||||||
|
|
||||||
|
${mockTimestamp} - Workitem has been updated. Modified files:
|
||||||
|
- file1.ts
|
||||||
|
- file2.ts
|
||||||
|
`;
|
||||||
|
expect(actualContentFromMock).toEqual(expectedContent);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle different status types', async () => {
|
||||||
|
const workitemContent = `## Workitem Title
|
||||||
|
|
||||||
|
This is a description of the workitem.
|
||||||
|
|
||||||
|
- [x] Jira: JIRA-123
|
||||||
|
- [ ] Implementation:
|
||||||
|
- [x] Active
|
||||||
|
|
||||||
|
### Log
|
||||||
|
|
||||||
|
Some existing log content.
|
||||||
|
`;
|
||||||
|
|
||||||
|
const workitem = {
|
||||||
|
name: 'workitem',
|
||||||
|
path: 'path/to/workitem.md',
|
||||||
|
title: 'Workitem Title',
|
||||||
|
description: 'This is a description of the workitem.',
|
||||||
|
jiraReference: 'JIRA-123',
|
||||||
|
implementation: '',
|
||||||
|
isActive: true
|
||||||
|
};
|
||||||
|
|
||||||
|
const status = 'deleted';
|
||||||
|
const files = ['file1.ts', 'file2.ts'];
|
||||||
|
|
||||||
|
// Mock fs.existsSync to return true for workitem file
|
||||||
|
(fs.existsSync as jest.Mock).mockReturnValue(true);
|
||||||
|
|
||||||
|
// Mock fs.readFileSync to return workitem content
|
||||||
|
(fs.readFileSync as jest.Mock).mockReturnValue(workitemContent);
|
||||||
|
|
||||||
|
// Mock fs.writeFileSync to capture the actual output
|
||||||
|
let actualContent = '';
|
||||||
|
(fs.writeFileSync as jest.Mock).mockImplementation((path, content) => {
|
||||||
|
actualContent = content;
|
||||||
|
});
|
||||||
|
|
||||||
|
await projectService.updateWorkitemWithImplementationLog(workitem, status, files);
|
||||||
|
|
||||||
|
// Verify that fs.existsSync and fs.readFileSync were called with the expected arguments
|
||||||
|
expect(fs.existsSync).toHaveBeenCalledWith('path/to/workitem.md');
|
||||||
|
expect(fs.readFileSync).toHaveBeenCalledWith('path/to/workitem.md', 'utf-8');
|
||||||
|
|
||||||
|
// Verify that fs.writeFileSync was called with the path
|
||||||
|
expect(fs.writeFileSync).toHaveBeenCalledWith(
|
||||||
|
'path/to/workitem.md',
|
||||||
|
expect.any(String),
|
||||||
|
'utf-8'
|
||||||
|
);
|
||||||
|
|
||||||
|
// Get the actual content from the mock
|
||||||
|
const actualContentFromMock = (fs.writeFileSync as jest.Mock).mock.calls[0][1];
|
||||||
|
|
||||||
|
// Verify the complete content equality
|
||||||
|
const expectedContent = `## Workitem Title
|
||||||
|
|
||||||
|
This is a description of the workitem.
|
||||||
|
|
||||||
|
- [x] Jira: JIRA-123
|
||||||
|
- [ ] Implementation:
|
||||||
|
- [x] Active
|
||||||
|
|
||||||
|
### Log
|
||||||
|
|
||||||
|
${mockTimestamp} - Workitem has been deleted. Removed files:
|
||||||
|
- file1.ts
|
||||||
|
- file2.ts
|
||||||
|
|
||||||
|
|
||||||
|
Some existing log content.
|
||||||
|
`;
|
||||||
|
expect(actualContentFromMock).toEqual(expectedContent);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle empty files array', async () => {
|
||||||
|
const workitemContent = `## Workitem Title
|
||||||
|
|
||||||
|
This is a description of the workitem.
|
||||||
|
|
||||||
|
- [x] Jira: JIRA-123
|
||||||
|
- [ ] Implementation:
|
||||||
|
- [x] Active
|
||||||
|
|
||||||
|
### Log
|
||||||
|
|
||||||
|
Some existing log content.
|
||||||
|
`;
|
||||||
|
|
||||||
|
const workitem = {
|
||||||
|
name: 'workitem',
|
||||||
|
path: 'path/to/workitem.md',
|
||||||
|
title: 'Workitem Title',
|
||||||
|
description: 'This is a description of the workitem.',
|
||||||
|
jiraReference: 'JIRA-123',
|
||||||
|
implementation: '',
|
||||||
|
isActive: true
|
||||||
|
};
|
||||||
|
|
||||||
|
const status = 'created';
|
||||||
|
const files: string[] = [];
|
||||||
|
|
||||||
|
// Mock fs.existsSync to return true for workitem file
|
||||||
|
(fs.existsSync as jest.Mock).mockReturnValue(true);
|
||||||
|
|
||||||
|
// Mock fs.readFileSync to return workitem content
|
||||||
|
(fs.readFileSync as jest.Mock).mockReturnValue(workitemContent);
|
||||||
|
|
||||||
|
// Mock fs.writeFileSync to capture the actual output
|
||||||
|
let actualContent = '';
|
||||||
|
(fs.writeFileSync as jest.Mock).mockImplementation((path, content) => {
|
||||||
|
actualContent = content;
|
||||||
|
});
|
||||||
|
|
||||||
|
await projectService.updateWorkitemWithImplementationLog(workitem, status, files);
|
||||||
|
|
||||||
|
// Verify that fs.existsSync and fs.readFileSync were called with the expected arguments
|
||||||
|
expect(fs.existsSync).toHaveBeenCalledWith('path/to/workitem.md');
|
||||||
|
expect(fs.readFileSync).toHaveBeenCalledWith('path/to/workitem.md', 'utf-8');
|
||||||
|
|
||||||
|
// Verify that fs.writeFileSync was called with the path
|
||||||
|
expect(fs.writeFileSync).toHaveBeenCalledWith(
|
||||||
|
'path/to/workitem.md',
|
||||||
|
expect.any(String),
|
||||||
|
'utf-8'
|
||||||
|
);
|
||||||
|
|
||||||
|
// Get the actual content from the mock
|
||||||
|
const actualContentFromMock = (fs.writeFileSync as jest.Mock).mock.calls[0][1];
|
||||||
|
|
||||||
|
// Verify the complete content equality
|
||||||
|
const expectedContent = `## Workitem Title
|
||||||
|
|
||||||
|
This is a description of the workitem.
|
||||||
|
|
||||||
|
- [x] Jira: JIRA-123
|
||||||
|
- [ ] Implementation:
|
||||||
|
- [x] Active
|
||||||
|
|
||||||
|
### Log
|
||||||
|
|
||||||
|
${mockTimestamp} - Workitem has been implemented. Created files:
|
||||||
|
No files were affected.
|
||||||
|
|
||||||
|
|
||||||
|
Some existing log content.
|
||||||
|
`;
|
||||||
|
expect(actualContentFromMock).toEqual(expectedContent);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw error if workitem file does not exist', async () => {
|
||||||
|
const workitem = {
|
||||||
|
name: 'workitem',
|
||||||
|
path: 'path/to/workitem.md',
|
||||||
|
title: 'Workitem Title',
|
||||||
|
description: 'This is a description of the workitem.',
|
||||||
|
jiraReference: 'JIRA-123',
|
||||||
|
implementation: '',
|
||||||
|
isActive: true
|
||||||
|
};
|
||||||
|
|
||||||
|
const status = 'created';
|
||||||
|
const files = ['file1.ts', 'file2.ts'];
|
||||||
|
|
||||||
|
// Mock fs.existsSync to return false for workitem file
|
||||||
|
(fs.existsSync as jest.Mock).mockReturnValue(false);
|
||||||
|
|
||||||
|
await expect(projectService.updateWorkitemWithImplementationLog(workitem, status, files))
|
||||||
|
.rejects.toThrow('Workitem file not found: path/to/workitem.md');
|
||||||
|
|
||||||
|
expect(fs.existsSync).toHaveBeenCalledWith('path/to/workitem.md');
|
||||||
|
expect(fs.readFileSync).not.toHaveBeenCalled();
|
||||||
|
expect(fs.writeFileSync).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -389,30 +389,6 @@ Feature: ${workitemName} (DRY RUN)
|
|||||||
return `File ${filePath} deleted successfully`;
|
return `File ${filePath} deleted successfully`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the name of the current workitem being processed
|
|
||||||
* This is a helper method to track file operations
|
|
||||||
* @returns The name of the current workitem or undefined
|
|
||||||
*/
|
|
||||||
private getCurrentWorkitemName(): string | undefined {
|
|
||||||
// This is a simple implementation that assumes the last part of the stack trace
|
|
||||||
// will contain the workitem name from the processWorkitem method
|
|
||||||
const stack = new Error().stack;
|
|
||||||
if (!stack) return undefined;
|
|
||||||
|
|
||||||
const lines = stack.split('\n');
|
|
||||||
for (const line of lines) {
|
|
||||||
if (line.includes('processWorkitem')) {
|
|
||||||
const match = /processWorkitem\s*\(\s*(\w+)/.exec(line);
|
|
||||||
if (match && match[1]) {
|
|
||||||
return match[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List files in a directory in the project repository
|
* List files in a directory in the project repository
|
||||||
* @param dirPath Path to the directory relative to the project repository root
|
* @param dirPath Path to the directory relative to the project repository root
|
||||||
|
@ -65,6 +65,7 @@ export class ProjectService {
|
|||||||
// Parse INFO.md content
|
// Parse INFO.md content
|
||||||
const repoHostMatch = infoContent.match(/- \[[ x]\] Repo host: (.*)/);
|
const repoHostMatch = infoContent.match(/- \[[ x]\] Repo host: (.*)/);
|
||||||
const repoUrlMatch = infoContent.match(/- \[[ x]\] Repo url: (.*)/);
|
const repoUrlMatch = infoContent.match(/- \[[ x]\] Repo url: (.*)/);
|
||||||
|
const targetBranchMatch = infoContent.match(/- \[[ x]\] Target branch: (.*)/);
|
||||||
const jiraComponentMatch = infoContent.match(/- \[[ x]\] Jira component: (.*)/);
|
const jiraComponentMatch = infoContent.match(/- \[[ x]\] Jira component: (.*)/);
|
||||||
|
|
||||||
const project = {
|
const project = {
|
||||||
@ -72,12 +73,14 @@ export class ProjectService {
|
|||||||
path: projectPath,
|
path: projectPath,
|
||||||
repoHost: repoHostMatch ? repoHostMatch[1].trim() : undefined,
|
repoHost: repoHostMatch ? repoHostMatch[1].trim() : undefined,
|
||||||
repoUrl: repoUrlMatch ? repoUrlMatch[1].trim() : undefined,
|
repoUrl: repoUrlMatch ? repoUrlMatch[1].trim() : undefined,
|
||||||
|
targetBranch: targetBranchMatch ? targetBranchMatch[1].trim() : undefined,
|
||||||
jiraComponent: jiraComponentMatch ? jiraComponentMatch[1].trim() : undefined
|
jiraComponent: jiraComponentMatch ? jiraComponentMatch[1].trim() : undefined
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(`ProjectService: Project info for ${projectName}:`);
|
console.log(`ProjectService: Project info for ${projectName}:`);
|
||||||
console.log(` - Repository host: ${project.repoHost || 'Not found'}`);
|
console.log(` - Repository host: ${project.repoHost || 'Not found'}`);
|
||||||
console.log(` - Repository URL: ${project.repoUrl || 'Not found'}`);
|
console.log(` - Repository URL: ${project.repoUrl || 'Not found'}`);
|
||||||
|
console.log(` - Target branch: ${project.targetBranch || 'Not found'}`);
|
||||||
console.log(` - Jira component: ${project.jiraComponent || 'Not found'}`);
|
console.log(` - Jira component: ${project.jiraComponent || 'Not found'}`);
|
||||||
|
|
||||||
return project;
|
return project;
|
||||||
@ -253,35 +256,72 @@ export class ProjectService {
|
|||||||
|
|
||||||
// Format the log message
|
// Format the log message
|
||||||
const timestamp = new Date().toISOString();
|
const timestamp = new Date().toISOString();
|
||||||
let logMessage = `\n\n<!-- Implementation Log: ${timestamp} -->\n`;
|
let logMessage = `${timestamp} - `;
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 'created':
|
case 'created':
|
||||||
logMessage += `<!-- Workitem has been implemented. Created files: -->\n`;
|
logMessage += `Workitem has been implemented. Created files:\n`;
|
||||||
break;
|
break;
|
||||||
case 'updated':
|
case 'updated':
|
||||||
logMessage += `<!-- Workitem has been updated. Modified files: -->\n`;
|
logMessage += `Workitem has been updated. Modified files:\n`;
|
||||||
break;
|
break;
|
||||||
case 'deleted':
|
case 'deleted':
|
||||||
logMessage += `<!-- Workitem has been deleted. Removed files: -->\n`;
|
logMessage += `Workitem has been deleted. Removed files:\n`;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the list of files
|
// Add the list of files
|
||||||
if (files.length > 0) {
|
if (files.length > 0) {
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
logMessage += `<!-- - ${file} -->\n`;
|
logMessage += `- ${file}\n`;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logMessage += `<!-- No files were affected. -->\n`;
|
logMessage += `No files were affected.\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append the log to the end of the file
|
// Add PR URL if available
|
||||||
|
if (workitem.pullRequestUrl) {
|
||||||
|
logMessage += `PR: ${workitem.pullRequestUrl}\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the Log section
|
||||||
|
const logSectionIndex = lines.findIndex(line => line.trim() === '### Log');
|
||||||
|
|
||||||
|
if (logSectionIndex >= 0) {
|
||||||
|
// Find the next section or the end of the file
|
||||||
|
let nextSectionIndex = lines.findIndex((line, index) =>
|
||||||
|
index > logSectionIndex && line.startsWith('###')
|
||||||
|
);
|
||||||
|
|
||||||
|
if (nextSectionIndex === -1) {
|
||||||
|
nextSectionIndex = lines.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the existing log content
|
||||||
|
const existingLogContent = lines.slice(logSectionIndex + 1, nextSectionIndex).join('\n');
|
||||||
|
|
||||||
|
// Insert the new log message after the "### Log" line and before any existing content
|
||||||
|
const beforeLog = lines.slice(0, logSectionIndex + 1);
|
||||||
|
const afterLog = lines.slice(nextSectionIndex);
|
||||||
|
|
||||||
|
// Combine the parts with the new log message followed by existing log content
|
||||||
|
// Add a blank line after the log title
|
||||||
|
const updatedLines = [...beforeLog, "", logMessage, ...lines.slice(logSectionIndex + 1, nextSectionIndex), ...afterLog];
|
||||||
|
const updatedContent = updatedLines.join('\n');
|
||||||
|
|
||||||
|
// Write the updated content back to the file
|
||||||
|
fs.writeFileSync(workitem.path, updatedContent, 'utf-8');
|
||||||
|
} else {
|
||||||
|
// If no Log section is found, append it to the end of the file
|
||||||
|
console.log(`No "### Log" section found in workitem ${workitem.name}, appending to the end`);
|
||||||
|
lines.push('\n### Log');
|
||||||
|
lines.push(''); // Add a blank line after the log title
|
||||||
lines.push(logMessage);
|
lines.push(logMessage);
|
||||||
|
|
||||||
// Write the updated content back to the file
|
// Write the updated content back to the file
|
||||||
const updatedContent = lines.join('\n');
|
const updatedContent = lines.join('\n');
|
||||||
fs.writeFileSync(workitem.path, updatedContent, 'utf-8');
|
fs.writeFileSync(workitem.path, updatedContent, 'utf-8');
|
||||||
|
}
|
||||||
|
|
||||||
// Update the workitem object (no need to change any properties)
|
// Update the workitem object (no need to change any properties)
|
||||||
return workitem;
|
return workitem;
|
||||||
|
@ -88,7 +88,7 @@ export class PullRequestService {
|
|||||||
title,
|
title,
|
||||||
body: description,
|
body: description,
|
||||||
head: branchName,
|
head: branchName,
|
||||||
base: 'main', // Assuming the default branch is 'main'
|
base: project.targetBranch || 'main', // Use target branch from project info or default to 'main'
|
||||||
},
|
},
|
||||||
{ headers }
|
{ headers }
|
||||||
);
|
);
|
||||||
@ -140,7 +140,7 @@ export class PullRequestService {
|
|||||||
title,
|
title,
|
||||||
body: description,
|
body: description,
|
||||||
head: branchName,
|
head: branchName,
|
||||||
base: 'main', // Assuming the default branch is 'main'
|
base: project.targetBranch || 'main', // Use target branch from project info or default to 'main'
|
||||||
},
|
},
|
||||||
{ headers }
|
{ headers }
|
||||||
);
|
);
|
||||||
|
@ -70,6 +70,12 @@ export class RepositoryService {
|
|||||||
// Clone the repository
|
// Clone the repository
|
||||||
await git.clone(project.repoUrl, projectRepoDir);
|
await git.clone(project.repoUrl, projectRepoDir);
|
||||||
|
|
||||||
|
// Checkout the target branch if specified
|
||||||
|
if (project.targetBranch) {
|
||||||
|
console.log(`Checking out target branch: ${project.targetBranch}`);
|
||||||
|
await this.checkoutBranch(projectRepoDir, project.targetBranch);
|
||||||
|
}
|
||||||
|
|
||||||
return projectRepoDir;
|
return projectRepoDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,6 +138,22 @@ export class RepositoryService {
|
|||||||
return patch || "No changes detected.";
|
return patch || "No changes detected.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checkout an existing branch in a repository
|
||||||
|
* @param repoDir Path to the repository
|
||||||
|
* @param branchName Name of the branch to checkout
|
||||||
|
*/
|
||||||
|
async checkoutBranch(repoDir: string, branchName: string): Promise<void> {
|
||||||
|
const git = simpleGit(repoDir);
|
||||||
|
try {
|
||||||
|
await git.checkout(branchName);
|
||||||
|
console.log(`Successfully checked out branch: ${branchName}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error checking out branch ${branchName}:`, error);
|
||||||
|
throw new Error(`Failed to checkout branch ${branchName}: ${error instanceof Error ? error.message : String(error)}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure git with credentials
|
* Configure git with credentials
|
||||||
* @param repoDir Path to the repository
|
* @param repoDir Path to the repository
|
||||||
|
@ -8,6 +8,7 @@ export interface Project {
|
|||||||
repoHost?: string;
|
repoHost?: string;
|
||||||
repoUrl?: string;
|
repoUrl?: string;
|
||||||
jiraComponent?: string;
|
jiraComponent?: string;
|
||||||
|
targetBranch?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Workitem {
|
export interface Workitem {
|
||||||
|
@ -22,6 +22,7 @@ A project info file follows the following format:
|
|||||||
|
|
||||||
- [ ] Repo host: <repo host url, eg https://gitea.fteamdev.valuya.be/ or https://github.com/organizations/Ebitda-SRL>
|
- [ ] Repo host: <repo host url, eg https://gitea.fteamdev.valuya.be/ or https://github.com/organizations/Ebitda-SRL>
|
||||||
- [ ] Repo url: <url of the project repository>
|
- [ ] Repo url: <url of the project repository>
|
||||||
|
- [ ] Target branch: <target branch for the PR>
|
||||||
- [ ] Jira component: <component of the jira>
|
- [ ] Jira component: <component of the jira>
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -41,7 +42,7 @@ A work item prompt file follows the following format:
|
|||||||
|
|
||||||
### Log
|
### Log
|
||||||
|
|
||||||
<log to be filled as the workitem is processed>
|
<log to be filled as the workitem is processed, implementation logs will be automatically added to this section>
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -66,5 +67,3 @@ The actual credentials are provided in the environment variables.
|
|||||||
- credential type: username/password
|
- credential type: username/password
|
||||||
- username variable: GITEA_USERNAME
|
- username variable: GITEA_USERNAME
|
||||||
- password variable: GITEA_PASSWORD
|
- password variable: GITEA_PASSWORD
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,4 +4,5 @@ Nitro backend server in quarkus
|
|||||||
|
|
||||||
- [x] Repo host: https://gitea.fteamdev.valuya.be/
|
- [x] Repo host: https://gitea.fteamdev.valuya.be/
|
||||||
- [x] Repo url: https://gitea.fteamdev.valuya.be/fiscalteam/nitro-back.git
|
- [x] Repo url: https://gitea.fteamdev.valuya.be/fiscalteam/nitro-back.git
|
||||||
|
- [x] Target branch: main
|
||||||
- [x] Jira component: nitro
|
- [x] Jira component: nitro
|
||||||
|
@ -6,4 +6,4 @@ The nitro-back backend should have a /test endpoint implemented returning the js
|
|||||||
|
|
||||||
- [ ] Jira:
|
- [ ] Jira:
|
||||||
- [ ] Implementation:
|
- [ ] Implementation:
|
||||||
- [ ] Active
|
- [x] Active
|
||||||
|
Loading…
x
Reference in New Issue
Block a user