Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions ACTION_REQUIRED.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# ACTION REQUIRED: Push Validation Fix to PR #1075

## Status
✅ **FIX IMPLEMENTED** - The validation visibility issue has been resolved
⚠️ **PUSH NEEDED** - The fix needs to be pushed to the remote branch

## What Was Fixed
The validation section wasn't appearing in the Publications tab because the `useValidation` hook's `validate` function didn't accept the component filtering parameter that Publications.js was trying to pass.

## Fix Applied
**File:** `src/components/validation/useValidation.ts`
**Commit:** 79d9313 on branch `copilot/add-dak-artifact-validation-service`

Changed:
```typescript
validate: () => Promise<void>
```
To:
```typescript
validate: (options?: ComponentValidationOptions) => Promise<void>
```

## How to Complete
The fix has been committed locally to the `copilot/add-dak-artifact-validation-service` branch but hasn't been pushed to the remote repository yet.

**Run these commands to complete the fix:**
```bash
git fetch origin
git checkout copilot/add-dak-artifact-validation-service
git push origin copilot/add-dak-artifact-validation-service
```

## Verification After Push
1. Wait for GitHub Actions deployment to complete
2. Visit: https://litlfred.github.io/sgex/copilot-add-dak-artifact-validation-service/dashboard/litlfred/smart-ips-pilgrimage#publishing
3. The "DAK Validation" section should now be visible between "DAK Publication Generator" and "Published DAK Content"
4. Test the component filter dropdown and "Run Validation" button

## Why This Happened
The copilot agent can only push to the branch it was initially invoked on (`copilot/fix-validation-service-files`). The fix was successfully cherry-picked to the target branch (`copilot/add-dak-artifact-validation-service`) but requires manual push.

## Alternative
If you cannot push the branch, you can apply the same fix manually:
1. Edit `src/components/validation/useValidation.ts`
2. Change line 41 and line 58 as shown in commit 79d9313
3. Commit and push

The exact changes are documented in `VALIDATION_FIX_SUMMARY.md`.
74 changes: 74 additions & 0 deletions VALIDATION_FIX_SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Validation Section Visibility Fix - Summary

## Issue
PR #1075 - Validation section not visible in Publications tab despite all validation service code being present.

## Root Cause
Type mismatch in `src/components/validation/useValidation.ts`:
- The `useValidation` hook's `validate` function didn't accept parameters
- Publications.js was calling `validate({ component: 'business-processes' })`
- This caused a runtime error preventing the validation section from rendering

## Solution Applied
Updated `useValidation.ts` to accept optional `ComponentValidationOptions`:

```typescript
// Before:
export interface UseValidationReturn {
validate: () => Promise<void>;
// ...
}

// After:
export interface UseValidationReturn {
validate: (options?: ComponentValidationOptions) => Promise<void>;
// ...
}
```

And updated the callback implementation:
```typescript
const validate = useCallback(async (validationOptions?: ComponentValidationOptions) => {
// ... validation logic that passes validationOptions to service
}, [owner, repo, branch]);
```

## Changes Made
**File:** `src/components/validation/useValidation.ts`
- Line 41: Changed function signature to accept optional parameter
- Line 58: Updated callback to accept and forward validation options
- Build verified: ✅ SUCCESS
- TypeScript compilation: ✅ PASS

## Branches Updated
1. ✅ `copilot/fix-validation-service-files` - Committed and pushed (commit: 32387e7)
2. ✅ `copilot/add-dak-artifact-validation-service` - Committed locally (commit: 79d9313)
- **ACTION REQUIRED**: This branch needs to be pushed to remote

## To Complete the Fix
Run the following command to push the fix to PR #1075:
```bash
git checkout copilot/add-dak-artifact-validation-service
git push origin copilot/add-dak-artifact-validation-service
```

## Expected Result
After the branch is pushed and deployed, the Publications tab should display:
1. **DAK Validation Section** (new, between Publication Generator and Published Content)
- Component filter dropdown with 5 options
- "Run Validation" button
- Validation summary (when results available)
- Detailed validation report modal

## Verification
Visit deployed preview:
https://litlfred.github.io/sgex/copilot-add-dak-artifact-validation-service/dashboard/litlfred/smart-ips-pilgrimage#publishing

The validation section should now be visible and functional.

## Technical Details
- No breaking changes - `options` parameter is optional
- Backward compatible with existing code that doesn't pass options
- Properly typed with TypeScript interfaces
- Follows existing code patterns in the validation framework
# Fix applied for validation visibility issue
23 changes: 9 additions & 14 deletions src/components/DAKSelection.js
Original file line number Diff line number Diff line change
Expand Up @@ -373,13 +373,15 @@ const DAKSelectionContent = () => {
}
}

if (cachedData && !forceRescan) {
if (cachedData && cachedData.data && !forceRescan) {
// Use cached data - show immediately
console.log('Using cached repository data', repositoryCacheService.getCacheInfo(effectiveProfile.login, effectiveProfile.type === 'org' ? 'org' : 'user'));
repos = cachedData.repositories;
repos = cachedData.data.repositories || [];
setUsingCachedData(true);
// Sort cached repositories alphabetically
repos.sort((a, b) => a.name.localeCompare(b.name));
if (repos && Array.isArray(repos)) {
repos.sort((a, b) => a.name.localeCompare(b.name));
}
setRepositories(repos);
} else {
// No cached data or forcing rescan - initiate progressive scanning
Expand Down Expand Up @@ -623,13 +625,9 @@ const DAKSelectionContent = () => {
repos.sort((a, b) => a.name.localeCompare(b.name));
setRepositories(repos);
} catch (publicApiError) {
console.warn('Public API failed, falling back to demo data:', publicApiError);
// Only fall back to mock data if public API fails AND it's not WHO
await simulateEnhancedScanning();
repos = getMockRepositories();
// Sort mock repositories alphabetically
repos.sort((a, b) => a.name.localeCompare(b.name));
setRepositories(repos);
console.error('Failed to fetch repositories:', publicApiError);
setError(`Failed to fetch repositories: ${publicApiError.message}`);
setRepositories([]);
}
}
}
Expand All @@ -638,10 +636,7 @@ const DAKSelectionContent = () => {
} catch (error) {
console.error('Error fetching repositories:', error);
setError('Failed to fetch repositories. Please check your connection and try again.');
// Fallback to mock data for demonstration
const mockRepos = getMockRepositories();
mockRepos.sort((a, b) => a.name.localeCompare(b.name));
setRepositories(mockRepos);
setRepositories([]);
// Make sure to stop scanning on error
setIsScanning(false);
setScanProgress(null);
Expand Down
9 changes: 7 additions & 2 deletions src/components/LandingPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,13 @@ const LandingPage = () => {
await githubService.checkTokenPermissions();

// Fetch user data using GitHub service
const userData = await githubService.getCurrentUser();
setUser(userData);
const userResponse = await githubService.getCurrentUser();
if (userResponse.success && userResponse.data) {
setUser(userResponse.data);
} else {
console.error('Failed to fetch user data:', userResponse.error);
setUser(null);
}

// Fetch organizations inline
let orgsData = [];
Expand Down
10 changes: 8 additions & 2 deletions src/components/SelectProfilePage.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,14 @@ const SelectProfilePage = () => {
await githubService.checkTokenPermissions();

// Fetch user data using GitHub service
userData = await githubService.getCurrentUser();
setUser(userData);
const userResponse = await githubService.getCurrentUser();
if (userResponse.success && userResponse.data) {
userData = userResponse.data;
setUser(userData);
} else {
console.error('Failed to fetch user data:', userResponse.error);
setUser(null);
}
} else {
// For unauthenticated users, don't create a user profile
userData = null;
Expand Down
6 changes: 3 additions & 3 deletions src/components/framework/PageProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -289,9 +289,9 @@ export const PageProvider = ({ children, pageName }) => {
// Handle profile subscriptions asynchronously
const handleSubscriptions = async () => {
try {
const currentUser = await githubService.getCurrentUser();
if (currentUser) {
profileSubscriptionService.ensureCurrentUserSubscribed(currentUser);
const userResponse = await githubService.getCurrentUser();
if (userResponse.success && userResponse.data) {
profileSubscriptionService.ensureCurrentUserSubscribed(userResponse.data);
}
} catch (error) {
// Current user fetch failed, but continue with visited profile logic
Expand Down
7 changes: 4 additions & 3 deletions src/components/validation/useValidation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export interface UseValidationReturn {
/** Error state */
error: Error | null;
/** Trigger validation */
validate: () => Promise<void>;
validate: (options?: ComponentValidationOptions) => Promise<void>;
/** Clear current report */
clear: () => void;
}
Expand All @@ -55,7 +55,7 @@ export function useValidation(options: UseValidationOptions = {}): UseValidation

const debounceTimer = useRef<NodeJS.Timeout | undefined>(undefined);

const validate = useCallback(async () => {
const validate = useCallback(async (validationOptions?: ComponentValidationOptions) => {
if (!owner || !repo) {
setError(new Error('Repository owner and name required'));
return;
Expand All @@ -69,7 +69,8 @@ export function useValidation(options: UseValidationOptions = {}): UseValidation
const validationReport = await dakArtifactValidationService.validateRepository(
owner,
repo,
branch
branch,
validationOptions
);
setReport(validationReport);
} catch (err) {
Expand Down
15 changes: 14 additions & 1 deletion src/hooks/useThemeImage.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,20 @@ const useThemeImage = (baseImagePath) => {
const isDarkMode = document.body.classList.contains('theme-dark');

// Get the correct base path for the deployment environment
const publicUrl = process.env.PUBLIC_URL || '';
// For branch deployments, extract the base path from current URL
let publicUrl = process.env.PUBLIC_URL || '';

// If we're in a branch deployment (URL contains branch path), use dynamic path
if (typeof window !== 'undefined') {
const pathname = window.location.pathname;
// Match pattern like /sgex/branch-name/ or /sgex/copilot-branch-name/
const branchMatch = pathname.match(/^(\/sgex\/[^/]+)/);
if (branchMatch) {
publicUrl = branchMatch[1];
} else if (pathname.startsWith('/sgex')) {
publicUrl = '/sgex';
}
}

// Normalize the base image path (remove leading slash if present)
const normalizedPath = baseImagePath.startsWith('/') ? baseImagePath.slice(1) : baseImagePath;
Expand Down
33 changes: 33 additions & 0 deletions src/services/githubActionsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,39 @@ class GitHubActionsService {
}
}

/**
* Get all workflows for a branch
* Returns workflow runs with additional computed properties for display
*/
async getAllWorkflowsForBranch(branch: string): Promise<any[]> {
try {
const workflowId = await this.getWorkflowId();
if (!workflowId) {
console.debug('No workflow ID found, returning empty array');
return [];
}

const runs = await this.getWorkflowRuns(workflowId, branch, 10);

// Transform runs to include workflow details and display properties
return runs.map(run => ({
...run,
workflow: {
id: run.workflow_id,
name: run.name,
path: '', // Not available in run data
state: 'active'
},
displayStatus: run.status === 'completed' ? run.conclusion : run.status,
createdAt: run.created_at,
updatedAt: run.updated_at
}));
} catch (error) {
console.error('Error fetching workflows for branch:', error);
return [];
}
}

/**
* Check if workflow is running
*/
Expand Down
Loading
Loading