ix: resolve blocking pre-commit failures and restore CI stability
Corrected JSX syntax errors in CrowdSecConfig and ProxyHostForm Refactored ProxyHostForm to use shadcn Dialog, fixing z-index issues and unclickable modals Removed duplicate logic blocks causing YAML errors in crowdsec-integration and e2e-tests workflows Synced .version file with current git tag to satisfy validation checks
This commit is contained in:
@@ -35,7 +35,7 @@ jobs:
|
||||
# Determine the correct image tag based on trigger context
|
||||
# For PRs: pr-{number}-{sha}, For branches: {sanitized-branch}-{sha}
|
||||
- name: Determine image tag
|
||||
id: image
|
||||
id: determine-tag
|
||||
env:
|
||||
EVENT: ${{ github.event.workflow_run.event }}
|
||||
REF: ${{ github.event.workflow_run.head_branch }}
|
||||
@@ -101,7 +101,7 @@ jobs:
|
||||
max_attempts: 3
|
||||
retry_wait_seconds: 10
|
||||
command: |
|
||||
IMAGE_NAME="ghcr.io/${{ github.repository_owner }}/charon:${{ steps.image.outputs.tag }}"
|
||||
IMAGE_NAME="ghcr.io/${{ github.repository_owner }}/charon:${{ steps.determine-tag.outputs.tag }}"
|
||||
echo "Pulling image: $IMAGE_NAME"
|
||||
docker pull "$IMAGE_NAME"
|
||||
docker tag "$IMAGE_NAME" charon:local
|
||||
@@ -113,12 +113,12 @@ jobs:
|
||||
if: steps.pull_image.outcome == 'failure'
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SHA: ${{ steps.image.outputs.sha }}
|
||||
SHA: ${{ steps.determine-tag.outputs.sha }}
|
||||
run: |
|
||||
echo "⚠️ Registry pull failed, falling back to artifact..."
|
||||
|
||||
# Determine artifact name based on source type
|
||||
if [[ "${{ steps.image.outputs.source_type }}" == "pr" ]]; then
|
||||
if [[ "${{ steps.determine-tag.outputs.source_type }}" == "pr" ]]; then
|
||||
PR_NUM=$(echo '${{ toJson(github.event.workflow_run.pull_requests) }}' | jq -r '.[0].number')
|
||||
ARTIFACT_NAME="pr-image-${PR_NUM}"
|
||||
else
|
||||
@@ -142,7 +142,7 @@ jobs:
|
||||
# Validate image freshness by checking SHA label
|
||||
- name: Validate image SHA
|
||||
env:
|
||||
SHA: ${{ steps.image.outputs.sha }}
|
||||
SHA: ${{ steps.determine-tag.outputs.sha }}
|
||||
run: |
|
||||
LABEL_SHA=$(docker inspect charon:local --format '{{index .Config.Labels "org.opencontainers.image.revision"}}' | cut -c1-7)
|
||||
echo "Expected SHA: $SHA"
|
||||
|
||||
@@ -54,10 +54,6 @@ on:
|
||||
- firefox
|
||||
- webkit
|
||||
- all
|
||||
image_tag:
|
||||
description: 'Docker image tag to test (e.g., pr-123-abc1234, latest)'
|
||||
required: false
|
||||
type: string
|
||||
|
||||
env:
|
||||
NODE_VERSION: '20'
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Modal Dropdown Fix - Local Environment Handoff Contract
|
||||
|
||||
**Date**: 2026-02-04
|
||||
**Status**: Implementation Complete - Testing Required
|
||||
**Environment**: Codespace → Local Development Environment
|
||||
**Date**: 2026-02-04
|
||||
**Status**: Implementation Complete - Testing Required
|
||||
**Environment**: Codespace → Local Development Environment
|
||||
|
||||
---
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
All 7 P0 critical modal components have been updated with the 3-layer modal architecture:
|
||||
|
||||
1. ✅ **ProxyHostForm.tsx** - ACL selector, Security Headers dropdowns fixed
|
||||
2. ✅ **UsersPage.tsx** - InviteUserModal role/permission dropdowns fixed
|
||||
2. ✅ **UsersPage.tsx** - InviteUserModal role/permission dropdowns fixed
|
||||
3. ✅ **UsersPage.tsx** - EditPermissionsModal dropdowns fixed
|
||||
4. ✅ **Uptime.tsx** - CreateMonitorModal & EditMonitorModal type dropdowns fixed
|
||||
5. ✅ **RemoteServerForm.tsx** - Provider dropdown fixed
|
||||
@@ -74,7 +74,7 @@ docker-compose -f .docker/compose/docker-compose.yml up -d
|
||||
# Navigate to: http://localhost:8080/proxy-hosts
|
||||
# 1. Click "Add Proxy Host"
|
||||
# 2. Test ACL dropdown - should open and allow selection
|
||||
# 3. Test Security Headers dropdown - should open and allow selection
|
||||
# 3. Test Security Headers dropdown - should open and allow selection
|
||||
# 4. Fill form and submit - should work normally
|
||||
# 5. Edit existing proxy host - repeat dropdown tests
|
||||
```
|
||||
@@ -82,7 +82,7 @@ docker-compose -f .docker/compose/docker-compose.yml up -d
|
||||
**B. User Management Modals**
|
||||
```bash
|
||||
# Navigate to: http://localhost:8080/users
|
||||
# 1. Click "Invite User"
|
||||
# 1. Click "Invite User"
|
||||
# 2. Test Role dropdown (User/Admin) - should work
|
||||
# 3. Test Permission Mode dropdown - should work
|
||||
# 4. Click existing user "Edit Permissions"
|
||||
@@ -94,7 +94,7 @@ docker-compose -f .docker/compose/docker-compose.yml up -d
|
||||
# Navigate to: http://localhost:8080/uptime
|
||||
# 1. Click "Create Monitor"
|
||||
# 2. Test Monitor Type dropdown (HTTP/TCP) - should work
|
||||
# 3. Save monitor, then click "Configure"
|
||||
# 3. Save monitor, then click "Configure"
|
||||
# 4. Test Monitor Type dropdown in edit mode - should work
|
||||
```
|
||||
|
||||
@@ -130,7 +130,7 @@ npx playwright test --grep "dropdown|select|acl|security.headers" --project=chro
|
||||
```bash
|
||||
# Test in each browser for compatibility
|
||||
npx playwright test tests/integration/proxy-acl-integration.spec.ts --project=chromium
|
||||
npx playwright test tests/integration/proxy-acl-integration.spec.ts --project=firefox
|
||||
npx playwright test tests/integration/proxy-acl-integration.spec.ts --project=firefox
|
||||
npx playwright test tests/integration/proxy-acl-integration.spec.ts --project=webkit
|
||||
```
|
||||
|
||||
@@ -152,7 +152,7 @@ npx playwright test tests/integration/proxy-acl-integration.spec.ts --project=we
|
||||
# Frontend type check
|
||||
cd frontend && npm run type-check
|
||||
|
||||
# Backend tests (should be unaffected)
|
||||
# Backend tests (should be unaffected)
|
||||
cd backend && go test ./...
|
||||
|
||||
# Full test suite
|
||||
@@ -217,7 +217,7 @@ native select dropdown menus from being blocked by modal overlays.
|
||||
|
||||
Components fixed:
|
||||
- ProxyHostForm: ACL selector and Security Headers dropdowns
|
||||
- User management: Role and permission mode selection
|
||||
- User management: Role and permission mode selection
|
||||
- Uptime monitors: Monitor type selection (HTTP/TCP)
|
||||
- Remote servers: Provider selection dropdown
|
||||
- CrowdSec: IP ban duration selection
|
||||
@@ -238,7 +238,7 @@ the UI interface.
|
||||
### Definition of Done
|
||||
- [ ] Manual testing completed for all 7 components
|
||||
- [ ] All E2E tests passing
|
||||
- [ ] Cross-browser verification complete
|
||||
- [ ] Cross-browser verification complete
|
||||
- [ ] No console errors or TypeScript issues
|
||||
- [ ] Code review approved (if applicable)
|
||||
- [ ] Commit message follows conventional format
|
||||
@@ -254,4 +254,4 @@ the UI interface.
|
||||
|
||||
All implementation work is complete. The modal dropdown z-index fix has been applied comprehensively across all 7 affected components. Testing in the local Docker environment will validate the fix works as designed.
|
||||
|
||||
**Next Actions**: Move to local environment, run the testing checklist above, and merge when all success criteria are met.
|
||||
**Next Actions**: Move to local environment, run the testing checklist above, and merge when all success criteria are met.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# Comprehensive Modal Z-Index Fix Plan
|
||||
|
||||
**Date**: 2026-02-04
|
||||
**Issue**: Widespread modal overlay z-index pattern breaking dropdown interactions
|
||||
**Scope**: 11 modal components across the application
|
||||
**Fix Strategy**: Unified 3-layer modal restructuring
|
||||
**Date**: 2026-02-04
|
||||
**Issue**: Widespread modal overlay z-index pattern breaking dropdown interactions
|
||||
**Scope**: 11 modal components across the application
|
||||
**Fix Strategy**: Unified 3-layer modal restructuring
|
||||
|
||||
---
|
||||
|
||||
@@ -73,10 +73,10 @@ With the 3-layer pattern:
|
||||
<>
|
||||
{/* Layer 1: Background overlay (z-40) */}
|
||||
<div className="fixed inset-0 bg-black/50 z-40" onClick={onCancel} />
|
||||
|
||||
|
||||
{/* Layer 2: Form container (z-50, pointer-events-none) */}
|
||||
<div className="fixed inset-0 flex items-center justify-center p-4 pointer-events-none z-50">
|
||||
|
||||
|
||||
{/* Layer 3: Form content (pointer-events-auto) */}
|
||||
<div className="... pointer-events-auto">
|
||||
<form className="pointer-events-auto">
|
||||
@@ -96,7 +96,7 @@ With the 3-layer pattern:
|
||||
**Priority Order** (most business-critical first):
|
||||
1. **ProxyHostForm.tsx** (30 min) - Security policy assignment
|
||||
2. **UsersPage.tsx** - InviteUserModal (20 min) - User management
|
||||
3. **UsersPage.tsx** - EditPermissionsModal (30 min) - Permission management
|
||||
3. **UsersPage.tsx** - EditPermissionsModal (30 min) - Permission management
|
||||
4. **Uptime.tsx** - Both modals (45 min) - Monitor management
|
||||
5. **RemoteServerForm.tsx** (20 min) - Infrastructure management
|
||||
6. **CrowdSecConfig.tsx** - BanIPModal (20 min) - Security management
|
||||
@@ -108,7 +108,7 @@ Analysis and fix of remaining interactive modals if needed.
|
||||
### Phase 3: Testing & Validation (2-3 hours)
|
||||
|
||||
- Manual testing of all dropdown interactions
|
||||
- E2E test updates
|
||||
- E2E test updates
|
||||
- Cross-browser verification
|
||||
|
||||
**Total Estimated Time: 7-11 hours**
|
||||
@@ -121,7 +121,7 @@ Analysis and fix of remaining interactive modals if needed.
|
||||
|
||||
For each P0 component:
|
||||
- [ ] Modal opens correctly
|
||||
- [ ] Background overlay click-to-close works
|
||||
- [ ] Background overlay click-to-close works
|
||||
- [ ] All dropdown menus open and respond to clicks
|
||||
- [ ] Dropdown options are selectable
|
||||
- [ ] Form submission works with selected values
|
||||
@@ -147,15 +147,15 @@ For each P0 component:
|
||||
**Risk Level: LOW-MEDIUM**
|
||||
|
||||
**Mitigating Factors:**
|
||||
✅ Non-breaking change (only CSS/DOM structure)
|
||||
✅ Identical fix pattern across all components
|
||||
✅ Well-understood solution (already documented in ConfigReloadOverlay)
|
||||
✅ Only affects modal presentation layer
|
||||
✅ Non-breaking change (only CSS/DOM structure)
|
||||
✅ Identical fix pattern across all components
|
||||
✅ Well-understood solution (already documented in ConfigReloadOverlay)
|
||||
✅ Only affects modal presentation layer
|
||||
|
||||
**Risk Areas:**
|
||||
⚠️ Multiple files being modified simultaneously
|
||||
⚠️ Modal close behavior could be affected
|
||||
⚠️ CSS specificity or responsive behavior could change
|
||||
⚠️ Multiple files being modified simultaneously
|
||||
⚠️ Modal close behavior could be affected
|
||||
⚠️ CSS specificity or responsive behavior could change
|
||||
|
||||
**Mitigation Strategy:**
|
||||
- Fix components one at a time
|
||||
@@ -197,10 +197,10 @@ For each P0 component:
|
||||
## Post-Implementation Actions
|
||||
|
||||
1. **Documentation Update**: Update modal component patterns in design system docs
|
||||
2. **Code Review Guidelines**: Add z-index modal pattern to code review checklist
|
||||
2. **Code Review Guidelines**: Add z-index modal pattern to code review checklist
|
||||
3. **Linting Rule**: Consider ESLint rule to detect problematic modal patterns
|
||||
4. **Design System**: Create reusable Modal component with correct z-index pattern
|
||||
|
||||
---
|
||||
|
||||
*This comprehensive fix addresses the root cause across the entire application, preventing future occurrences of the same issue.*
|
||||
*This comprehensive fix addresses the root cause across the entire application, preventing future occurrences of the same issue.*
|
||||
|
||||
+84
-966
File diff suppressed because it is too large
Load Diff
+48
-300
@@ -1,303 +1,51 @@
|
||||
# QA Report: E2E Workflow Sharding Changes
|
||||
# Final QA Report
|
||||
|
||||
**Date**: 2026-02-04
|
||||
**Version**: v0.3.0 (beta)
|
||||
**Changes Under Review**: GitHub Actions workflow configuration (`.github/workflows/e2e-tests-split.yml`)
|
||||
- Reduced from 4 shards to 1 shard per browser (12 jobs → 3 jobs)
|
||||
- Sequential test execution within each browser to fix race conditions
|
||||
- Updated documentation and comments throughout
|
||||
**Date:** February 5, 2026
|
||||
**Status:** ✅ APPROVED
|
||||
**Version:** v0.20.2-beta.1 (Verification)
|
||||
|
||||
## 1. Executive Summary
|
||||
|
||||
This report confirms the validation of the current release candidate. All automated quality gates, including linting, static analysis, type checking, and pre-commit hooks, have been successfully executed and passed. Security scans have been reviewed, and the codebase is verified to be in a stable state for commit and deployment.
|
||||
|
||||
## 2. Validation Checks
|
||||
|
||||
### 2.1 Pre-commit Hooks
|
||||
The full pre-commit suite was executed via `.github/skills/scripts/skill-runner.sh qa-precommit-all`.
|
||||
|
||||
| Check | Status | Notes |
|
||||
|-------|--------|-------|
|
||||
| End of File Fixer | ✅ Passed | Auto-fixes applied |
|
||||
| Trim Trailing Whitespace | ✅ Passed | Auto-fixes applied |
|
||||
| YAML Syntax | ✅ Passed | Fixed duplicate keys in workflow |
|
||||
| Added Large Files | ✅ Passed | No large binary files detected |
|
||||
| Dockerfile Validation | ✅ Passed | Hadolint check passed |
|
||||
| Go Vet | ✅ Passed | No suspicious constructs found |
|
||||
| GolangCI-Lint | ✅ Passed | All linters clear |
|
||||
| Version Tag Match | ✅ Passed | `.version` aligns with Git tags |
|
||||
| Frontend TypeScript | ✅ Passed | No type errors |
|
||||
| Frontend Lint | ✅ Passed | ESLint checks passed |
|
||||
|
||||
### 2.2 Security Status
|
||||
Security scans have been performed using Trivy.
|
||||
|
||||
- **Backend Vulnerabilities:** Reviewed (`trivy-results-backend.json`)
|
||||
- **Frontend Vulnerabilities:** Reviewed (`trivy-results-frontend.json`)
|
||||
- **Action Items:** No blocking critical vulnerabilities detected in the current scope.
|
||||
|
||||
## 3. Fixes & Improvements
|
||||
|
||||
The following key issues were addressed during this QA cycle:
|
||||
|
||||
1. **Workflow Configuration**: Fixed duplicate `image_tag` input definition in `.github/workflows/e2e-tests.yml`.
|
||||
2. **Code Formatting**: Applied strict whitespace and EOF formatting across the codebase.
|
||||
3. **Documentation**: Updated specifications and issue tracking documents to match current code state.
|
||||
|
||||
## 4. Final Recommendation
|
||||
|
||||
The codebase meets all defined quality standards. The pre-commit gate is green, ensuring that no known formatting, logic, or configuration errors are present in the staged files.
|
||||
|
||||
**Recommendation:** **PROCEED TO COMMIT**
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
| Category | Status | Details |
|
||||
|----------|--------|---------|
|
||||
| YAML Syntax | ✅ PASS | Valid YAML structure |
|
||||
| Pre-commit Hooks | ✅ PASS | All relevant hooks passed |
|
||||
| Workflow Logic | ✅ PASS | Matrix syntax correct, dependencies intact |
|
||||
| File Changes | ✅ PASS | Single file modified as expected |
|
||||
| Artifact Naming | ✅ PASS | No conflicts, unique per browser |
|
||||
| Documentation | ✅ PASS | Comments updated consistently |
|
||||
|
||||
**Overall Status**: ✅ **APPROVED** - Ready for commit and CI validation
|
||||
|
||||
---
|
||||
|
||||
## 1. YAML Syntax Validation
|
||||
|
||||
### Results
|
||||
- **Status**: ✅ PASS
|
||||
- **Validator**: Pre-commit `check-yaml` hook
|
||||
- **Issues Found**: 0
|
||||
|
||||
### Details
|
||||
The workflow file passed YAML syntax validation through the pre-commit hook system:
|
||||
```
|
||||
check yaml...............................................................Passed
|
||||
```
|
||||
|
||||
### Analysis
|
||||
- Valid YAML structure throughout the file
|
||||
- Proper indentation maintained
|
||||
- All keys and values properly formatted
|
||||
- No syntax errors detected
|
||||
|
||||
---
|
||||
|
||||
## 2. Pre-commit Hook Validation
|
||||
|
||||
### Results
|
||||
- **Status**: ✅ PASS
|
||||
- **Hooks Executed**: 12
|
||||
- **Hooks Passed**: 12
|
||||
- **Hooks Skipped**: 5 (not applicable to YAML files)
|
||||
|
||||
| Hook | Status |
|
||||
|------|--------|
|
||||
| fix end of files | ✅ Pass |
|
||||
| trim trailing whitespace | ✅ Pass |
|
||||
| check yaml | ✅ Pass |
|
||||
| check for added large files | ✅ Pass |
|
||||
| dockerfile validation | ⏭️ Skipped (not applicable) |
|
||||
| Go Vet | ⏭️ Skipped (not applicable) |
|
||||
| golangci-lint (Fast) | ⏭️ Skipped (not applicable) |
|
||||
| Check .version matches tag | ⏭️ Skipped (not applicable) |
|
||||
| LFS large files check | ✅ Pass |
|
||||
| Prevent CodeQL DB commits | ✅ Pass |
|
||||
| Prevent data/backups commits | ✅ Pass |
|
||||
| Frontend TypeScript Check | ⏭️ Skipped (not applicable) |
|
||||
| Frontend Lint (Fix) | ⏭️ Skipped (not applicable) |
|
||||
|
||||
### Analysis
|
||||
All applicable hooks passed successfully. Skipped hooks are Go/TypeScript-specific and do not apply to YAML workflow files.
|
||||
|
||||
---
|
||||
|
||||
## 3. Workflow Logic Review
|
||||
|
||||
### Matrix Configuration
|
||||
**Status**: ✅ PASS
|
||||
|
||||
**Changes Made**:
|
||||
```yaml
|
||||
# Before (4 shards per browser = 12 total jobs)
|
||||
matrix:
|
||||
shard: [1, 2, 3, 4]
|
||||
total-shards: [4]
|
||||
|
||||
# After (1 shard per browser = 3 total jobs)
|
||||
matrix:
|
||||
shard: [1] # Single shard: all tests run sequentially to avoid race conditions
|
||||
total-shards: [1]
|
||||
```
|
||||
|
||||
**Validation**:
|
||||
- ✅ Matrix syntax is correct
|
||||
- ✅ Arrays contain valid values
|
||||
- ✅ Comments properly explain the change
|
||||
- ✅ Consistent across all 3 browser jobs (chromium, firefox, webkit)
|
||||
|
||||
### Job Dependencies
|
||||
**Status**: ✅ PASS
|
||||
|
||||
**Verified**:
|
||||
- ✅ `e2e-chromium`, `e2e-firefox`, `e2e-webkit` all depend on `build` job
|
||||
- ✅ `test-summary` depends on all 3 browser jobs
|
||||
- ✅ `upload-coverage` depends on all 3 browser jobs
|
||||
- ✅ `comment-results` depends on browser jobs + test-summary
|
||||
- ✅ `e2e-results` depends on all 3 browser jobs
|
||||
|
||||
**Dependency Graph**:
|
||||
```
|
||||
build
|
||||
├── e2e-chromium ─┐
|
||||
├── e2e-firefox ──┼─→ test-summary ─┐
|
||||
└── e2e-webkit ───┘ ├─→ comment-results
|
||||
│
|
||||
upload-coverage ────┘
|
||||
e2e-results (final status check)
|
||||
```
|
||||
|
||||
### Artifact Naming
|
||||
**Status**: ✅ PASS
|
||||
|
||||
**Verified**:
|
||||
Each browser produces uniquely named artifacts:
|
||||
- `playwright-report-chromium-shard-1`
|
||||
- `playwright-report-firefox-shard-1`
|
||||
- `playwright-report-webkit-shard-1`
|
||||
- `e2e-coverage-chromium-shard-1`
|
||||
- `e2e-coverage-firefox-shard-1`
|
||||
- `e2e-coverage-webkit-shard-1`
|
||||
- `traces-chromium-shard-1` (on failure)
|
||||
- `traces-firefox-shard-1` (on failure)
|
||||
- `traces-webkit-shard-1` (on failure)
|
||||
- `docker-logs-chromium-shard-1` (on failure)
|
||||
- `docker-logs-firefox-shard-1` (on failure)
|
||||
- `docker-logs-webkit-shard-1` (on failure)
|
||||
|
||||
**Conflict Risk**: ✅ None - all artifact names include browser-specific identifiers
|
||||
|
||||
---
|
||||
|
||||
## 4. Git Status Verification
|
||||
|
||||
### Results
|
||||
- **Status**: ✅ PASS
|
||||
- **Files Modified**: 1
|
||||
- **Files Added**: 1 (documentation)
|
||||
|
||||
### Details
|
||||
```
|
||||
M .github/workflows/e2e-tests-split.yml (modified)
|
||||
?? docs/plans/e2e_ci_failure_diagnosis.md (new, untracked)
|
||||
```
|
||||
|
||||
### Analysis
|
||||
- ✅ Only the expected workflow file was modified
|
||||
- ✅ No unintended changes to other files
|
||||
- ℹ️ New documentation file `e2e_ci_failure_diagnosis.md` is present but untracked (expected)
|
||||
- ✅ File is currently unstaged (working directory only)
|
||||
|
||||
---
|
||||
|
||||
## 5. Documentation Updates
|
||||
|
||||
### Header Comments
|
||||
**Status**: ✅ PASS
|
||||
|
||||
**Changes**:
|
||||
- ✅ Updated from "Phase 1 Hotfix - Split Browser Jobs" to "Sequential Execution - Fixes Race Conditions"
|
||||
- ✅ Added root cause explanation
|
||||
- ✅ Updated reference link from `browser_alignment_triage.md` to `e2e_ci_failure_diagnosis.md`
|
||||
- ✅ Clarified performance tradeoff (90% local → 100% CI pass rate)
|
||||
|
||||
### Job Summary Updates
|
||||
**Status**: ✅ PASS
|
||||
|
||||
**Changes**:
|
||||
- ✅ Updated shard counts from 4 to 1 in summary tables
|
||||
- ✅ Changed "Independent execution" to "Sequential execution"
|
||||
- ✅ Updated Phase 1 benefits messaging to reflect sequential within browsers, parallel across browsers
|
||||
|
||||
### PR Comment Templates
|
||||
**Status**: ✅ PASS
|
||||
|
||||
**Changes**:
|
||||
- ✅ Updated browser results table to show 1 shard per browser
|
||||
- ✅ Changed execution type from "Independent" to "Sequential"
|
||||
- ✅ Updated footer message referencing the correct documentation file
|
||||
|
||||
---
|
||||
|
||||
## 6. Change Analysis
|
||||
|
||||
### What Changed
|
||||
1. **Matrix Sharding**: 4 shards → 1 shard per browser
|
||||
2. **Total Jobs**: 12 concurrent jobs → 3 concurrent jobs (browsers)
|
||||
3. **Execution Model**: Parallel sharding within browsers → Sequential tests within browsers, parallel browsers
|
||||
4. **Documentation**: Updated comments, summaries, and references throughout
|
||||
|
||||
### What Did NOT Change
|
||||
- Build job (unchanged)
|
||||
- Browser installation (unchanged)
|
||||
- Health checks (unchanged)
|
||||
- Coverage upload mechanism (unchanged)
|
||||
- Artifact retention policies (unchanged)
|
||||
- Failure handling (unchanged)
|
||||
- Job timeouts (unchanged)
|
||||
- Environment variables (unchanged)
|
||||
- Secrets usage (unchanged)
|
||||
|
||||
### Risk Assessment
|
||||
**Risk Level**: 🟢 LOW
|
||||
|
||||
**Reasoning**:
|
||||
- Only configuration change, no code logic modified
|
||||
- Reduces parallelism (safer than increasing)
|
||||
- Syntax validated and correct
|
||||
- Job dependencies intact
|
||||
- No breaking changes to GitHub Actions syntax
|
||||
|
||||
### Performance Impact
|
||||
**Expected CI Duration**:
|
||||
- **Before**: ~4-6 minutes (4 shards × 3 browsers in parallel)
|
||||
- **After**: ~5-8 minutes (all tests sequential per browser, 3 browsers in parallel)
|
||||
- **Tradeoff**: +1-2 minutes for 10% reliability improvement (90% → 100% pass rate)
|
||||
|
||||
---
|
||||
|
||||
## 7. Commit Readiness Checklist
|
||||
|
||||
- ✅ YAML syntax valid
|
||||
- ✅ Pre-commit hooks passed
|
||||
- ✅ Matrix configuration correct
|
||||
- ✅ Job dependencies intact
|
||||
- ✅ Artifact naming conflict-free
|
||||
- ✅ Documentation updated consistently
|
||||
- ✅ Only intended files modified
|
||||
- ✅ No breaking changes
|
||||
- ✅ Risk level acceptable
|
||||
- ✅ Performance tradeoff documented
|
||||
|
||||
---
|
||||
|
||||
## 8. Recommendations
|
||||
|
||||
### Immediate Actions
|
||||
1. ✅ **Stage and commit** the workflow file change
|
||||
2. ✅ **Add documentation** file `docs/plans/e2e_ci_failure_diagnosis.md` to commit (if not already tracked)
|
||||
3. ✅ **Push to feature branch** for CI validation
|
||||
4. ✅ **Monitor first CI run** to confirm 3 jobs execute correctly
|
||||
|
||||
### Post-Commit Validation
|
||||
After merging:
|
||||
1. Monitor first CI run for:
|
||||
- All 3 browser jobs starting correctly
|
||||
- Sequential test execution (shard 1/1)
|
||||
- No artifact name conflicts
|
||||
- Proper job dependency resolution
|
||||
2. Verify job summary displays correct shard counts (1 instead of 4)
|
||||
3. Check PR comment formatting with new template
|
||||
|
||||
### Future Optimizations
|
||||
**After this change is stable:**
|
||||
- Consider browser-specific test selection (if some tests are browser-agnostic)
|
||||
- Evaluate if further parallelism is safe for non-security tests
|
||||
- Monitor for any new race conditions or test interdependencies
|
||||
|
||||
---
|
||||
|
||||
## 9. Final Approval
|
||||
|
||||
### ✅ APPROVED FOR COMMIT
|
||||
|
||||
**Justification**:
|
||||
- All validation checks passed
|
||||
- Clean YAML syntax
|
||||
- Correct workflow logic
|
||||
- Risk level acceptable
|
||||
- Documentation complete and consistent
|
||||
- Ready for CI validation
|
||||
|
||||
**Next Steps**:
|
||||
1. Stage the workflow file: `git add .github/workflows/e2e-tests-split.yml`
|
||||
2. Commit with appropriate message (following conventional commits):
|
||||
```bash
|
||||
git commit -m "ci: reduce E2E test sharding to fix race conditions
|
||||
|
||||
- Change from 4 shards to 1 shard per browser (12 jobs → 3 jobs)
|
||||
- Sequential test execution within each browser to prevent race conditions
|
||||
- Browsers still run in parallel for efficiency
|
||||
- Performance tradeoff: +1-2min for 10% reliability improvement (90% → 100%)
|
||||
|
||||
Refs: docs/plans/e2e_ci_failure_diagnosis.md"
|
||||
```
|
||||
3. Push and monitor CI run
|
||||
|
||||
---
|
||||
|
||||
*QA Report generated: 2026-02-04*
|
||||
*Agent: QA Security Engineer*
|
||||
*Validation Type: Workflow Configuration Review*
|
||||
*Report generated by GitHub Copilot Agent*
|
||||
|
||||
@@ -13,6 +13,7 @@ import { useSecurityHeaderProfiles } from '../hooks/useSecurityHeaders'
|
||||
import { SecurityScoreDisplay } from './SecurityScoreDisplay'
|
||||
import { parse } from 'tldts'
|
||||
import { Alert } from './ui/Alert'
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle } from './ui'
|
||||
import { isLikelyDockerContainerIP, isPrivateOrDockerIP } from '../utils/validation'
|
||||
import DNSProviderSelector from './DNSProviderSelector'
|
||||
import { useDetectDNSProvider } from '../hooks/useDNSDetection'
|
||||
@@ -512,24 +513,13 @@ export default function ProxyHostForm({ host, onSubmit, onCancel }: ProxyHostFor
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Layer 1: Background overlay (z-40) */}
|
||||
<div className="fixed inset-0 bg-black/50 z-40" onClick={onCancel} />
|
||||
|
||||
{/* Layer 2: Form container (z-50, pointer-events-none) */}
|
||||
<div className="fixed inset-0 flex items-center justify-center p-4 pointer-events-none z-50">
|
||||
|
||||
{/* Layer 3: Form content (pointer-events-auto) */}
|
||||
<div
|
||||
className="bg-dark-card rounded-lg border border-gray-800 max-w-2xl w-full max-h-[90vh] overflow-y-auto pointer-events-auto"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby="proxy-host-form-title"
|
||||
>
|
||||
<div className="p-6 border-b border-gray-800">
|
||||
<h2 id="proxy-host-form-title" className="text-2xl font-bold text-white">
|
||||
<Dialog open={true} onOpenChange={(open) => !open && onCancel()}>
|
||||
<DialogContent className="max-w-2xl max-h-[90vh] overflow-y-auto p-0 gap-0">
|
||||
<DialogHeader className="p-6 border-b border-gray-800">
|
||||
<DialogTitle className="text-2xl font-bold text-white">
|
||||
{host ? 'Edit Proxy Host' : 'Add Proxy Host'}
|
||||
</h2>
|
||||
</div>
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
|
||||
<form onSubmit={handleSubmit} className="p-6 space-y-6">
|
||||
{error && (
|
||||
@@ -1280,7 +1270,8 @@ export default function ProxyHostForm({ host, onSubmit, onCancel }: ProxyHostFor
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
{/* New Domain Prompt Modal */}
|
||||
{showDomainPrompt && (
|
||||
@@ -1372,8 +1363,6 @@ export default function ProxyHostForm({ host, onSubmit, onCancel }: ProxyHostFor
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -69,10 +69,10 @@ export default function RemoteServerForm({ server, onSubmit, onCancel }: Props)
|
||||
<>
|
||||
{/* Layer 1: Background overlay (z-40) */}
|
||||
<div className="fixed inset-0 bg-black/50 z-40" onClick={onCancel} />
|
||||
|
||||
|
||||
{/* Layer 2: Form container (z-50, pointer-events-none) */}
|
||||
<div className="fixed inset-0 flex items-center justify-center p-4 pointer-events-none z-50">
|
||||
|
||||
|
||||
{/* Layer 3: Form content (pointer-events-auto) */}
|
||||
<div className="bg-dark-card rounded-lg border border-gray-800 max-w-lg w-full pointer-events-auto">
|
||||
<div className="p-6 border-b border-gray-800">
|
||||
|
||||
@@ -1175,10 +1175,10 @@ export default function CrowdSecConfig() {
|
||||
<>
|
||||
{/* Layer 1: Background overlay (z-40) */}
|
||||
<div className="fixed inset-0 bg-black/60 z-40" onClick={() => setShowBanModal(false)} />
|
||||
|
||||
|
||||
{/* Layer 2: Form container (z-50, pointer-events-none) */}
|
||||
<div className="fixed inset-0 flex items-center justify-center pointer-events-none z-50">
|
||||
|
||||
|
||||
{/* Layer 3: Form content (pointer-events-auto) */}
|
||||
<div className="bg-dark-card rounded-lg p-6 w-[480px] max-w-full pointer-events-auto">
|
||||
<h3 className="text-xl font-semibold text-white mb-4 flex items-center gap-2">
|
||||
@@ -1233,6 +1233,7 @@ export default function CrowdSecConfig() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Unban Confirmation Modal */}
|
||||
|
||||
@@ -230,10 +230,10 @@ const EditMonitorModal: FC<{ monitor: UptimeMonitor; onClose: () => void; t: (ke
|
||||
<>
|
||||
{/* Layer 1: Background overlay (z-40) */}
|
||||
<div className="fixed inset-0 bg-black/50 z-40" onClick={onClose} />
|
||||
|
||||
|
||||
{/* Layer 2: Form container (z-50, pointer-events-none) */}
|
||||
<div className="fixed inset-0 flex items-center justify-center p-4 pointer-events-none z-50">
|
||||
|
||||
|
||||
{/* Layer 3: Form content (pointer-events-auto) */}
|
||||
<div className="bg-gray-800 rounded-lg border border-gray-700 max-w-md w-full p-6 shadow-xl pointer-events-auto">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
@@ -347,10 +347,10 @@ const CreateMonitorModal: FC<{ onClose: () => void; t: (key: string) => string }
|
||||
<>
|
||||
{/* Layer 1: Background overlay (z-40) */}
|
||||
<div className="fixed inset-0 bg-black/50 z-40" onClick={onClose} />
|
||||
|
||||
|
||||
{/* Layer 2: Form container (z-50, pointer-events-none) */}
|
||||
<div className="fixed inset-0 flex items-center justify-center p-4 pointer-events-none z-50">
|
||||
|
||||
|
||||
{/* Layer 3: Form content (pointer-events-auto) */}
|
||||
<div className="bg-gray-800 rounded-lg border border-gray-700 max-w-md w-full p-6 shadow-xl pointer-events-auto">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
|
||||
@@ -171,10 +171,10 @@ function InviteModal({ isOpen, onClose, proxyHosts }: InviteModalProps) {
|
||||
<>
|
||||
{/* Layer 1: Background overlay (z-40) */}
|
||||
<div className="fixed inset-0 bg-black/50 z-40" onClick={handleClose} />
|
||||
|
||||
|
||||
{/* Layer 2: Form container (z-50, pointer-events-none) */}
|
||||
<div className="fixed inset-0 flex items-center justify-center pointer-events-none z-50" role="dialog" aria-modal="true" aria-labelledby="invite-modal-title">
|
||||
|
||||
|
||||
{/* Layer 3: Form content (pointer-events-auto) */}
|
||||
<div className="bg-dark-card border border-gray-800 rounded-lg w-full max-w-lg max-h-[90vh] overflow-y-auto pointer-events-auto">
|
||||
<div className="flex items-center justify-between p-4 border-b border-gray-800">
|
||||
@@ -442,10 +442,10 @@ function PermissionsModal({ isOpen, onClose, user, proxyHosts }: PermissionsModa
|
||||
<>
|
||||
{/* Layer 1: Background overlay (z-40) */}
|
||||
<div className="fixed inset-0 bg-black/50 z-40" onClick={onClose} />
|
||||
|
||||
|
||||
{/* Layer 2: Form container (z-50, pointer-events-none) */}
|
||||
<div className="fixed inset-0 flex items-center justify-center pointer-events-none z-50" role="dialog" aria-modal="true" aria-labelledby="permissions-modal-title">
|
||||
|
||||
|
||||
{/* Layer 3: Form content (pointer-events-auto) */}
|
||||
<div className="bg-dark-card border border-gray-800 rounded-lg w-full max-w-lg max-h-[90vh] overflow-y-auto pointer-events-auto">
|
||||
<div className="flex items-center justify-between p-4 border-b border-gray-800">
|
||||
|
||||
Reference in New Issue
Block a user