Skip to content

feat: initialize Task 3 - Enhanced Semantic Search Capabilities #126

feat: initialize Task 3 - Enhanced Semantic Search Capabilities

feat: initialize Task 3 - Enhanced Semantic Search Capabilities #126

Workflow file for this run

name: Pull Request Checks
on:
pull_request:
branches: [ main, development ]
types: [opened, synchronize, reopened, ready_for_review]
jobs:
pr-quality-gate:
name: PR Quality Gate
runs-on: ubuntu-latest
if: github.event.pull_request.draft == false
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Get full history for diff analysis
- name: Set up Python 3.11
uses: actions/setup-python@v4
with:
python-version: 3.11
- name: Cache pip dependencies
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: pip-${{ runner.os }}-3.11-${{ hashFiles('pyproject.toml') }}
restore-keys: |
pip-${{ runner.os }}-3.11-
- name: Install dependencies
shell: bash
run: |
echo "Installing dependencies..."
python -m pip install --upgrade pip
pip install -e .
pip install ruff pytest
- name: Verify environment
shell: bash
run: |
python --version
pip --version
- name: Quick lint check (changed files only)
shell: bash
run: |
echo "🔍 Quick lint check on changed files..."
CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD -- '*.py' | tr '\n' ' ')
if [ -n "$CHANGED_FILES" ]; then
echo "Changed files: $CHANGED_FILES"
python -m ruff check $CHANGED_FILES --output-format=github
python -m ruff format --check $CHANGED_FILES
echo "✅ Lint check passed"
else
echo "No Python files changed"
fi
- name: Run tests on changed modules
shell: bash
run: |
echo "🧪 Running tests for changed modules..."
CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD -- 'src/**/*.py')
if [ -n "$CHANGED_FILES" ]; then
python -m pytest tests/ -v --tb=short
echo "✅ Tests passed"
else
echo "No source files changed, skipping tests"
fi
- name: Validate atomic design on changes
run: |
echo "🏗️ Validating atomic design on changed files..."
python << 'EOF'
import os
import subprocess
import sys
# Get changed files
result = subprocess.run(['git', 'diff', '--name-only', 'origin/${{ github.base_ref }}...HEAD', '--', 'src/'],
capture_output=True, text=True)
changed_files = result.stdout.strip().split('\n') if result.stdout.strip() else []
violations = []
for file_path in changed_files:
if file_path and os.path.exists(file_path) and file_path.endswith('.py'):
with open(file_path, 'r') as f:
line_count = sum(1 for line in f)
if line_count > 500:
violations.append(f"{file_path}: {line_count} lines (exceeds 500-line limit)")
# Check if file is in correct atomic location
if 'src/uckn/core/' in file_path:
if not any(atomic in file_path for atomic in ['atoms/', 'molecules/', 'organisms/']):
violations.append(f"{file_path}: not in atomic structure (atoms/molecules/organisms)")
if violations:
print("❌ Atomic design violations in changed files:")
for violation in violations:
print(f" {violation}")
sys.exit(1)
else:
print("✅ Changed files comply with atomic design")
EOF
- name: Check imports and dependencies
run: |
echo "🔍 Checking import structure..."
python << 'EOF'
import os
import ast
import sys
def check_imports(file_path):
"""Check for proper import structure"""
violations = []
try:
with open(file_path, 'r') as f:
tree = ast.parse(f.read())
for node in ast.walk(tree):
if isinstance(node, ast.ImportFrom):
if node.module and 'framework.' in node.module:
violations.append(f"Legacy framework import: {node.module}")
except:
pass # Skip files that can't be parsed
return violations
all_violations = []
for root, dirs, files in os.walk("src/uckn"):
for file in files:
if file.endswith(".py"):
file_path = os.path.join(root, file)
violations = check_imports(file_path)
all_violations.extend([f"{file_path}: {v}" for v in violations])
if all_violations:
print("❌ Import violations:")
for violation in all_violations:
print(f" {violation}")
sys.exit(1)
else:
print("✅ Import structure is clean")
EOF
pr-coverage:
name: Coverage Check
runs-on: ubuntu-latest
if: github.event.pull_request.draft == false
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup pixi with cache fallback
id: setup-pixi-step # Added ID for checking cache status
uses: prefix-dev/setup-pixi@v0.8.10
with:
pixi-version: v0.49.0
cache: false # Temporarily disable during GitHub cache service outage
manifest-path: pyproject.toml
- name: Log pixi cache status
shell: bash
run: |
if [ "${{ steps.setup-pixi-step.outputs.cache-hit }}" == "true" ]; then
echo "✅ Pixi cache hit!"
else
echo "⚠️ Pixi cache miss or failed to restore."
fi
- name: Install pixi dependencies (with retry)
shell: bash
run: |
n=0
until [ "$n" -ge 3 ]
do
if pixi install; then
echo "✅ Installation successful"
break
elif [ "$n" -eq 2 ]; then
echo "⚠️ Install failed, retrying..."
pixi install && break
fi
n=$((n+1))
echo "pixi install failed, retrying ($n/3)..."
sleep 5
done
if [ "$n" -ge 3 ]; then
echo "❌ Failed to install pixi dependencies after multiple retries."
exit 1
fi
- name: Activate pixi environment
shell: bash
run: |
eval "$(pixi shell --env-hook bash)"
- name: Install project in editable mode
shell: bash
run: |
pixi run install-editable
- name: Generate coverage report
shell: bash
run: |
echo "📊 Generating coverage report..."
pixi run pytest tests/ --cov=src/uckn --cov-report=json --cov-report=term
# Check coverage threshold
python << 'EOF'
import json
with open('coverage.json', 'r') as f:
coverage_data = json.load(f)
total_coverage = coverage_data['totals']['percent_covered']
print(f"Total coverage: {total_coverage:.1f}%")
if total_coverage < 40:
print(f"❌ Coverage below threshold: {total_coverage:.1f}% < 40%")
exit(1)
else:
print(f"✅ Coverage meets threshold: {total_coverage:.1f}% >= 40%")
EOF
pr-docs:
name: Documentation Check
runs-on: ubuntu-latest
if: github.event.pull_request.draft == false
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Fetch base branch
run: |
git fetch origin ${{ github.base_ref }}:${{ github.base_ref }}
- name: Check documentation updates
run: |
echo "📚 Checking documentation..."
# Check if significant changes need doc updates
CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD)
SRC_CHANGES=$(echo "$CHANGED_FILES" | grep -E '^src/' | wc -l)
DOC_CHANGES=$(echo "$CHANGED_FILES" | grep -E '\.(md|rst)$' | wc -l)
echo "Source file changes: $SRC_CHANGES"
echo "Documentation changes: $DOC_CHANGES"
if [ "$SRC_CHANGES" -gt 5 ] && [ "$DOC_CHANGES" -eq 0 ]; then
echo "⚠️ Significant source changes detected but no documentation updates"
echo "Consider updating documentation for major changes"
else
echo "✅ Documentation status acceptable"
fi
pr-summary:
name: PR Summary
runs-on: ubuntu-latest
needs: [pr-quality-gate, pr-coverage, pr-docs]
if: always()
steps:
- name: Generate PR summary
run: |
echo "## 🎯 Pull Request Quality Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [ "${{ needs.pr-quality-gate.result }}" == "success" ]; then
echo "✅ **Quality Gate**: Passed" >> $GITHUB_STEP_SUMMARY
else
echo "❌ **Quality Gate**: Failed" >> $GITHUB_STEP_SUMMARY
fi
if [ "${{ needs.pr-coverage.result }}" == "success" ]; then
echo "✅ **Coverage**: Acceptable" >> $GITHUB_STEP_SUMMARY
else
echo "❌ **Coverage**: Below threshold" >> $GITHUB_STEP_SUMMARY
fi
if [ "${{ needs.pr-docs.result }}" == "success" ]; then
echo "✅ **Documentation**: Checked" >> $GITHUB_STEP_SUMMARY
else
echo "⚠️ **Documentation**: Needs attention" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "### UCKN Framework Standards" >> $GITHUB_STEP_SUMMARY
echo "- Atomic design structure enforced" >> $GITHUB_STEP_SUMMARY
echo "- File size limits validated (≤500 lines)" >> $GITHUB_STEP_SUMMARY
echo "- Import structure verified" >> $GITHUB_STEP_SUMMARY
echo "- Test coverage maintained" >> $GITHUB_STEP_SUMMARY