mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-01 20:23:36 +00:00
Changes from pull-request
This commit is contained in:
@@ -1154,7 +1154,17 @@ export function BoardView() {
|
||||
open={showCreatePRDialog}
|
||||
onOpenChange={setShowCreatePRDialog}
|
||||
worktree={selectedWorktreeForAction}
|
||||
onCreated={() => {
|
||||
onCreated={(prUrl) => {
|
||||
// If a PR was created and we have the worktree branch, update all features on that branch with the PR URL
|
||||
if (prUrl && selectedWorktreeForAction?.branch) {
|
||||
const branchName = selectedWorktreeForAction.branch;
|
||||
hookFeatures
|
||||
.filter((f) => f.branchName === branchName)
|
||||
.forEach((feature) => {
|
||||
updateFeature(feature.id, { prUrl });
|
||||
persistFeatureUpdate(feature.id, { prUrl });
|
||||
});
|
||||
}
|
||||
setWorktreeRefreshKey((k) => k + 1);
|
||||
setSelectedWorktreeForAction(null);
|
||||
}}
|
||||
|
||||
@@ -52,6 +52,8 @@ import {
|
||||
MoreVertical,
|
||||
AlertCircle,
|
||||
GitBranch,
|
||||
GitPullRequest,
|
||||
ExternalLink,
|
||||
ChevronDown,
|
||||
ChevronUp,
|
||||
Brain,
|
||||
@@ -697,6 +699,26 @@ export const KanbanCard = memo(function KanbanCard({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* PR URL Display */}
|
||||
{feature.prUrl && (
|
||||
<div className="mb-2">
|
||||
<a
|
||||
href={feature.prUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
onPointerDown={(e) => e.stopPropagation()}
|
||||
className="inline-flex items-center gap-1.5 text-[11px] text-purple-500 hover:text-purple-400 transition-colors"
|
||||
title={feature.prUrl}
|
||||
data-testid={`pr-url-${feature.id}`}
|
||||
>
|
||||
<GitPullRequest className="w-3 h-3 shrink-0" />
|
||||
<span className="truncate max-w-[150px]">Pull Request</span>
|
||||
<ExternalLink className="w-2.5 h-2.5 shrink-0" />
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Steps Preview */}
|
||||
{showSteps && feature.steps && feature.steps.length > 0 && (
|
||||
<div className="mb-3 space-y-1.5">
|
||||
|
||||
@@ -30,7 +30,7 @@ interface CreatePRDialogProps {
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
worktree: WorktreeInfo | null;
|
||||
onCreated: () => void;
|
||||
onCreated: (prUrl?: string) => void;
|
||||
}
|
||||
|
||||
export function CreatePRDialog({
|
||||
@@ -201,7 +201,8 @@ export function CreatePRDialog({
|
||||
// Only call onCreated() if an actual operation completed
|
||||
// This prevents unnecessary refreshes when user cancels
|
||||
if (operationCompletedRef.current) {
|
||||
onCreated();
|
||||
// Pass the PR URL if one was created
|
||||
onCreated(prUrl || undefined);
|
||||
}
|
||||
onOpenChange(false);
|
||||
// State reset is handled by useEffect when open becomes false
|
||||
|
||||
@@ -305,6 +305,7 @@ export interface Feature {
|
||||
planningMode?: PlanningMode; // Planning mode for this feature
|
||||
planSpec?: PlanSpec; // Generated spec/plan data
|
||||
requirePlanApproval?: boolean; // Whether to pause and require manual approval before implementation
|
||||
prUrl?: string; // Pull request URL when a PR has been created for this feature
|
||||
}
|
||||
|
||||
// Parsed task from spec (for spec and full planning modes)
|
||||
|
||||
@@ -2610,4 +2610,127 @@ test.describe("Worktree Integration Tests", () => {
|
||||
// worktreePath should not exist in the feature data (worktrees are created at execution time)
|
||||
expect(featureData.worktreePath).toBeUndefined();
|
||||
});
|
||||
|
||||
// ==========================================================================
|
||||
// PR URL Tracking Tests
|
||||
// ==========================================================================
|
||||
|
||||
test("feature should support prUrl field for tracking pull request URLs", async ({
|
||||
page,
|
||||
}) => {
|
||||
await setupProjectWithPath(page, testRepo.path);
|
||||
await page.goto("/");
|
||||
await waitForNetworkIdle(page);
|
||||
await waitForBoardView(page);
|
||||
|
||||
// Create a feature
|
||||
await clickAddFeature(page);
|
||||
await fillAddFeatureDialog(page, "Feature for PR URL test", {
|
||||
category: "Testing",
|
||||
});
|
||||
await confirmAddFeature(page);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// Verify feature was created
|
||||
const featuresDir = path.join(testRepo.path, ".automaker", "features");
|
||||
const featureDirs = fs.readdirSync(featuresDir);
|
||||
const featureDir = featureDirs.find((dir) => {
|
||||
const featureFilePath = path.join(featuresDir, dir, "feature.json");
|
||||
if (fs.existsSync(featureFilePath)) {
|
||||
const data = JSON.parse(fs.readFileSync(featureFilePath, "utf-8"));
|
||||
return data.description === "Feature for PR URL test";
|
||||
}
|
||||
return false;
|
||||
});
|
||||
expect(featureDir).toBeDefined();
|
||||
|
||||
// Manually update the feature.json file to add prUrl (simulating what happens after PR creation)
|
||||
const featureFilePath = path.join(featuresDir, featureDir!, "feature.json");
|
||||
const featureData = JSON.parse(fs.readFileSync(featureFilePath, "utf-8"));
|
||||
featureData.prUrl = "https://github.com/test/repo/pull/123";
|
||||
fs.writeFileSync(featureFilePath, JSON.stringify(featureData, null, 2));
|
||||
|
||||
// Reload the page to pick up the change
|
||||
await page.reload();
|
||||
await waitForNetworkIdle(page);
|
||||
await waitForBoardView(page);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// Verify the PR URL link is displayed on the card
|
||||
const prUrlLink = page.locator(`[data-testid="pr-url-${featureData.id}"]`);
|
||||
await expect(prUrlLink).toBeVisible({ timeout: 5000 });
|
||||
await expect(prUrlLink).toHaveText(/Pull Request/);
|
||||
await expect(prUrlLink).toHaveAttribute(
|
||||
"href",
|
||||
"https://github.com/test/repo/pull/123"
|
||||
);
|
||||
});
|
||||
|
||||
test("prUrl should persist when updating feature", async ({ page }) => {
|
||||
await setupProjectWithPath(page, testRepo.path);
|
||||
await page.goto("/");
|
||||
await waitForNetworkIdle(page);
|
||||
await waitForBoardView(page);
|
||||
|
||||
// Create a feature
|
||||
await clickAddFeature(page);
|
||||
await fillAddFeatureDialog(page, "Feature with PR URL persistence", {
|
||||
category: "Testing",
|
||||
});
|
||||
await confirmAddFeature(page);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// Find the feature file
|
||||
const featuresDir = path.join(testRepo.path, ".automaker", "features");
|
||||
const featureDirs = fs.readdirSync(featuresDir);
|
||||
const featureDir = featureDirs.find((dir) => {
|
||||
const featureFilePath = path.join(featuresDir, dir, "feature.json");
|
||||
if (fs.existsSync(featureFilePath)) {
|
||||
const data = JSON.parse(fs.readFileSync(featureFilePath, "utf-8"));
|
||||
return data.description === "Feature with PR URL persistence";
|
||||
}
|
||||
return false;
|
||||
});
|
||||
expect(featureDir).toBeDefined();
|
||||
|
||||
// Add prUrl to the feature
|
||||
const featureFilePath = path.join(featuresDir, featureDir!, "feature.json");
|
||||
let featureData = JSON.parse(fs.readFileSync(featureFilePath, "utf-8"));
|
||||
const originalPrUrl = "https://github.com/test/repo/pull/456";
|
||||
featureData.prUrl = originalPrUrl;
|
||||
fs.writeFileSync(featureFilePath, JSON.stringify(featureData, null, 2));
|
||||
|
||||
// Reload the page
|
||||
await page.reload();
|
||||
await waitForNetworkIdle(page);
|
||||
await waitForBoardView(page);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// Open edit dialog by double-clicking the feature card
|
||||
const featureCard = page.getByText("Feature with PR URL persistence");
|
||||
await featureCard.dblclick();
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// Wait for edit dialog to open
|
||||
const editDialog = page.locator('[data-testid="edit-feature-dialog"]');
|
||||
await expect(editDialog).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Update the description
|
||||
const descInput = page.locator(
|
||||
'[data-testid="edit-feature-description"] textarea'
|
||||
);
|
||||
await descInput.fill("Feature with PR URL persistence - updated");
|
||||
|
||||
// Save the feature
|
||||
const saveButton = page.locator('[data-testid="confirm-edit-feature"]');
|
||||
await saveButton.click();
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// Verify prUrl was preserved
|
||||
featureData = JSON.parse(fs.readFileSync(featureFilePath, "utf-8"));
|
||||
expect(featureData.prUrl).toBe(originalPrUrl);
|
||||
expect(featureData.description).toBe(
|
||||
"Feature with PR URL persistence - updated"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user