diff --git a/.github/workflows/auto-assign-pr.yml b/.github/workflows/auto-assign-pr.yml new file mode 100644 index 0000000..161024f --- /dev/null +++ b/.github/workflows/auto-assign-pr.yml @@ -0,0 +1,40 @@ +# Auto Assign Copilot (or any username) to every new pull request. +# Tweak the username(s) below as needed! + +name: Auto Assign Copilot to PRs + +on: + pull_request: + types: [opened] + +jobs: + auto-assign: + runs-on: ubuntu-latest + steps: + - name: Assign Copilot (or others) to new PRs + uses: actions/github-script@main + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + // Assign PRs to Copilot or other users + const copilotUsername = "copilot"; // <-- TUNE ME! + const assignees = [copilotUsername]; // Or: ["copilot","anotheruser"] + const currentAssignees = context.payload.pull_request.assignees.map(u => u.login); + if (!assignees.every(a => currentAssignees.includes(a))) { + console.log(`PR has assignees to add. Attempting to assign ${assignees.join(", ")}...`); + + try { + await github.rest.issues.addAssignees({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.payload.pull_request.number, + assignees + }); + console.log(`✅ Assigned ${assignees.join(", ")} to PR #${context.payload.pull_request.number}`); + } catch (error) { + console.log(`⚠️ Failed to assign users: ${error.message}`); + console.log("Note: This may be due to insufficient permissions or the user not being a collaborator."); + } + } else { + console.log(`ℹ️ Already assigned: ${assignees.join(", ")} on PR #${context.payload.pull_request.number}`); + } \ No newline at end of file diff --git a/.github/workflows/auto-complete-cicd-review.yml b/.github/workflows/auto-complete-cicd-review.yml new file mode 100644 index 0000000..37365d2 --- /dev/null +++ b/.github/workflows/auto-complete-cicd-review.yml @@ -0,0 +1,439 @@ +name: "Complete CI/CD Agent Review Pipeline" + +on: + schedule: + # Run every 12 hours (at 00:00 and 12:00 UTC) + - cron: '0 0,12 * * *' + push: + branches: + - main + - master + pull_request: + types: [opened, synchronize, reopened] + workflow_dispatch: + inputs: + skip_tests: + description: 'Skip test execution' + required: false + default: 'false' + type: boolean + skip_docs: + description: 'Skip documentation review' + required: false + default: 'false' + type: boolean + +permissions: + contents: write + pull-requests: write + issues: write + checks: write + actions: read + +jobs: + # Step 1: Code Cleanliness Review + code-cleanliness: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@main + with: + fetch-depth: 0 + + - name: Run Code Cleanliness Analysis + run: | + echo "🔍 Running code cleanliness analysis..." + + # Create results directory + mkdir -p /tmp/review-results + + echo "## Code Cleanliness Analysis" > /tmp/review-results/cleanliness.md + echo "" >> /tmp/review-results/cleanliness.md + + # Find large files + echo "### Large Files (>500 lines):" >> /tmp/review-results/cleanliness.md + find . -type f \( -name "*.py" -o -name "*.js" -o -name "*.ts" -o -name "*.java" -o -name "*.go" -o -name "*.cs" \) \ + ! -path "*/node_modules/*" ! -path "*/dist/*" ! -path "*/build/*" ! -path "*/.venv/*" \ + -exec sh -c 'lines=$(wc -l < "$1"); if [ "$lines" -gt 500 ]; then echo "$lines lines: $1"; fi' _ {} \; \ + | sort -rn >> /tmp/review-results/cleanliness.md || echo "No large files found" >> /tmp/review-results/cleanliness.md + + echo "✅ Code cleanliness analysis complete" + + - name: Upload Cleanliness Report + uses: actions/upload-artifact@main + with: + name: cleanliness-report + path: /tmp/review-results/cleanliness.md + retention-days: 30 + + # Step 2: Test Review and Execution + test-review: + runs-on: ubuntu-latest + if: github.event.inputs.skip_tests != 'true' + strategy: + fail-fast: false + matrix: + test-type: [unit, integration, e2e] + steps: + - name: Checkout code + uses: actions/checkout@main + + - name: Setup Test Environment + run: | + echo "🧪 Setting up test environment for ${{ matrix.test-type }} tests..." + mkdir -p /tmp/review-results + + - name: Setup Node.js + uses: actions/setup-node@main + with: + node-version: '20' + continue-on-error: true + + - name: Setup Python + uses: actions/setup-python@main + with: + python-version: '3.11' + continue-on-error: true + + - name: Install Playwright for E2E + if: matrix.test-type == 'e2e' + run: | + if [ -f "package.json" ]; then + npm install + npm install -D @playwright/test playwright + npx playwright install --with-deps chromium firefox webkit + fi + pip install pytest playwright pytest-playwright + python -m playwright install --with-deps chromium firefox webkit + continue-on-error: true + + - name: Run Tests - ${{ matrix.test-type }} + run: | + echo "Running ${{ matrix.test-type }} tests..." + + case "${{ matrix.test-type }}" in + unit) + if [ -f "package.json" ] && grep -q '"test"' package.json; then + npm test -- --testPathPattern="unit" || npm test || echo "Unit tests not configured" + fi + pytest tests/unit/ 2>/dev/null || echo "Python unit tests not configured" + ;; + integration) + pytest tests/integration/ 2>/dev/null || echo "Integration tests not configured" + npm test -- --testPathPattern="integration" 2>/dev/null || echo "JS integration tests not configured" + ;; + e2e) + # Playwright tests + npx playwright test 2>/dev/null || echo "Playwright JS tests not configured" + pytest tests/e2e/ 2>/dev/null || pytest --browser chromium 2>/dev/null || echo "Playwright Python tests not configured" + ;; + esac + continue-on-error: true + + - name: Upload Test Results + uses: actions/upload-artifact@main + if: always() + with: + name: test-results-${{ matrix.test-type }} + path: | + test-results/ + playwright-report/ + .pytest_cache/ + coverage/ + retention-days: 30 + continue-on-error: true + + # Step 3: Documentation Review + documentation-review: + runs-on: ubuntu-latest + if: github.event.inputs.skip_docs != 'true' + steps: + - name: Checkout code + uses: actions/checkout@main + + - name: Analyze Documentation + run: | + echo "📚 Analyzing documentation..." + + mkdir -p /tmp/review-results + + echo "## Documentation Analysis" > /tmp/review-results/documentation.md + echo "" >> /tmp/review-results/documentation.md + + # Check for essential files + echo "### Essential Documentation Files:" >> /tmp/review-results/documentation.md + for doc in README.md CONTRIBUTING.md LICENSE.md CHANGELOG.md CODE_OF_CONDUCT.md SECURITY.md; do + if [ -f "$doc" ]; then + word_count=$(wc -w < "$doc" 2>/dev/null || echo 0) + echo "✅ $doc ($word_count words)" >> /tmp/review-results/documentation.md + else + echo "❌ $doc (missing)" >> /tmp/review-results/documentation.md + fi + done + + # Check README quality + if [ -f "README.md" ]; then + echo "" >> /tmp/review-results/documentation.md + echo "### README.md Content Check:" >> /tmp/review-results/documentation.md + for section in "Installation" "Usage" "Features" "Contributing" "License" "Documentation" "Examples" "API"; do + if grep -qi "$section" README.md; then + echo "✅ Contains '$section' section" >> /tmp/review-results/documentation.md + else + echo "⚠️ Missing '$section' section" >> /tmp/review-results/documentation.md + fi + done + fi + + echo "✅ Documentation analysis complete" + + - name: Upload Documentation Report + uses: actions/upload-artifact@main + with: + name: documentation-report + path: /tmp/review-results/documentation.md + retention-days: 30 + + # Step 4: Build and Functionality Check + build-check: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@main + + - name: Setup Build Environment + run: | + echo "🏗️ Setting up build environment..." + + - name: Setup Node.js + uses: actions/setup-node@main + with: + node-version: '20' + continue-on-error: true + + - name: Setup Python + uses: actions/setup-python@main + with: + python-version: '3.11' + continue-on-error: true + + - name: Setup Go + uses: actions/setup-go@main + with: + go-version: 'stable' + continue-on-error: true + + - name: Build Project + id: build + run: | + echo "BUILD_SUCCESS=false" >> $GITHUB_OUTPUT + + # Node.js + if [ -f "package.json" ]; then + npm install + if grep -q '"build"' package.json; then + npm run build && echo "BUILD_SUCCESS=true" >> $GITHUB_OUTPUT + else + echo "BUILD_SUCCESS=no-build-script" >> $GITHUB_OUTPUT + fi + fi + + # Python + if [ -f "requirements.txt" ]; then + pip install -r requirements.txt && echo "BUILD_SUCCESS=true" >> $GITHUB_OUTPUT + fi + + # Go + if [ -f "go.mod" ]; then + go build ./... && echo "BUILD_SUCCESS=true" >> $GITHUB_OUTPUT + fi + continue-on-error: true + + - name: Upload Build Status + run: | + mkdir -p /tmp/review-results + echo "## Build Status" > /tmp/review-results/build.md + echo "" >> /tmp/review-results/build.md + echo "Build result: ${{ steps.build.outputs.BUILD_SUCCESS }}" >> /tmp/review-results/build.md + + - name: Upload Build Report + uses: actions/upload-artifact@main + with: + name: build-report + path: /tmp/review-results/build.md + retention-days: 30 + + # Step 5: Consolidate Results and Create Report + consolidate-results: + runs-on: ubuntu-latest + needs: [code-cleanliness, test-review, documentation-review, build-check] + if: always() + steps: + - name: Checkout code + uses: actions/checkout@main + + - name: Download All Reports + uses: actions/download-artifact@main + with: + path: /tmp/all-reports + continue-on-error: true + + - name: Consolidate Reports + run: | + echo "📊 Consolidating all reports..." + + mkdir -p /tmp/final-report + + cat > /tmp/final-report/complete-review.md << 'EOF' + # Complete CI/CD Agent Review Report + + **Review Date:** $(date -u +"%Y-%m-%d %H:%M:%S UTC") + **Repository:** ${{ github.repository }} + **Branch:** ${{ github.ref_name }} + **Trigger:** ${{ github.event_name }} + + ## Executive Summary + + This comprehensive review covers: + - ✅ Code cleanliness and file size analysis + - ✅ Test coverage and Playwright integration + - ✅ Documentation completeness and quality + - ✅ Build functionality verification + + EOF + + # Append individual reports + if [ -d "/tmp/all-reports" ]; then + echo "" >> /tmp/final-report/complete-review.md + echo "## Detailed Findings" >> /tmp/final-report/complete-review.md + + for report in /tmp/all-reports/*/*.md; do + if [ -f "$report" ]; then + echo "" >> /tmp/final-report/complete-review.md + cat "$report" >> /tmp/final-report/complete-review.md + echo "" >> /tmp/final-report/complete-review.md + fi + done + fi + + cat /tmp/final-report/complete-review.md + + - name: Create or Update Review Issue + uses: actions/github-script@main + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const fs = require('fs'); + let report = ''; + + try { + report = fs.readFileSync('/tmp/final-report/complete-review.md', 'utf8'); + } catch (error) { + report = '## Review Report\n\nError consolidating reports. Please check workflow logs.'; + } + + const date = new Date().toISOString().split('T')[0]; + const title = `Complete CI/CD Review - ${date}`; + + const body = `${report} + + ## Next Steps - Amazon Q Review + + After reviewing these GitHub Copilot agent findings, Amazon Q will provide additional insights: + - Security analysis + - Performance optimization opportunities + - AWS best practices + - Enterprise architecture patterns + + ## Action Items Summary + + - [ ] Review and address code cleanliness issues + - [ ] Fix or improve test coverage + - [ ] Update documentation as needed + - [ ] Resolve build issues + - [ ] Wait for Amazon Q review for additional insights + + --- + *This issue was automatically generated by the Complete CI/CD Review workflow.* + *Amazon Q review will follow automatically.* + `; + + // Check for existing review issues + try { + const issues = await github.rest.issues.listForRepo({ + owner: context.repo.owner, + repo: context.repo.repo, + state: 'open', + labels: ['ci-cd-review', 'automated'], + per_page: 10 + }); + + const recentIssue = issues.data.find(issue => { + const createdAt = new Date(issue.created_at); + const hoursSinceCreation = (Date.now() - createdAt) / (1000 * 60 * 60); + return hoursSinceCreation < 24; + }); + + if (recentIssue) { + console.log(`Recent issue found: #${recentIssue.number}, updating`); + try { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: recentIssue.number, + body: `## Updated Review (${date})\n\n${report}` + }); + console.log(`✅ Updated existing issue #${recentIssue.number}`); + } catch (error) { + console.log(`⚠️ Failed to update existing issue: ${error.message}`); + } + } else { + try { + await github.rest.issues.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title: title, + body: body, + labels: ['ci-cd-review', 'automated', 'needs-review'] + }); + console.log(`✅ Created new review issue`); + } catch (error) { + console.log(`⚠️ Failed to create new issue: ${error.message}`); + } + } + } catch (error) { + console.log(`⚠️ Failed to list existing issues: ${error.message}`); + console.log("Note: This may be due to insufficient permissions."); + } + + - name: Upload Final Report + uses: actions/upload-artifact@main + with: + name: complete-review-report + path: /tmp/final-report/complete-review.md + retention-days: 90 + + # Step 6: Trigger Amazon Q Review + trigger-amazonq: + runs-on: ubuntu-latest + needs: consolidate-results + if: always() + steps: + - name: Trigger Amazon Q Review Workflow + uses: actions/github-script@main + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + console.log('Triggering Amazon Q review workflow...'); + + try { + await github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: 'auto-amazonq-review.yml', + ref: context.ref + }); + console.log('✅ Amazon Q review workflow triggered successfully'); + } catch (error) { + console.log(`⚠️ Could not trigger Amazon Q review: ${error.message}`); + console.log('Amazon Q workflow may not be installed yet'); + } diff --git a/.github/workflows/auto-copilot-code-cleanliness-review.yml b/.github/workflows/auto-copilot-code-cleanliness-review.yml new file mode 100644 index 0000000..5bd21cb --- /dev/null +++ b/.github/workflows/auto-copilot-code-cleanliness-review.yml @@ -0,0 +1,141 @@ +name: "Periodic Code Cleanliness Review" + +on: + schedule: + # Run every 12 hours (at 00:00 and 12:00 UTC) + - cron: '0 0,12 * * *' + workflow_dispatch: # Allow manual trigger + +permissions: + contents: write + pull-requests: write + issues: write + +jobs: + code-cleanliness-review: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@main + with: + fetch-depth: 0 # Full history for better analysis + + - name: Analyze Large Files + id: analyze + run: | + echo "## Large Files Analysis" > /tmp/analysis.md + echo "" >> /tmp/analysis.md + echo "Files larger than 500 lines that may benefit from splitting:" >> /tmp/analysis.md + echo "" >> /tmp/analysis.md + + # Find files larger than 500 lines (excluding common large files) + find . -type f \( -name "*.py" -o -name "*.js" -o -name "*.ts" -o -name "*.java" -o -name "*.go" -o -name "*.cs" -o -name "*.rb" \) \ + ! -path "*/node_modules/*" \ + ! -path "*/dist/*" \ + ! -path "*/build/*" \ + ! -path "*/.venv/*" \ + ! -path "*/vendor/*" \ + -exec wc -l {} \; | \ + awk '$1 > 500 {print $1 " lines: " $2}' | \ + sort -rn >> /tmp/analysis.md || echo "No large files found" >> /tmp/analysis.md + + echo "" >> /tmp/analysis.md + echo "## Code Complexity Analysis" >> /tmp/analysis.md + echo "" >> /tmp/analysis.md + echo "Files with potential complexity issues:" >> /tmp/analysis.md + + # Find files with many functions/classes (basic heuristic) + for ext in py js ts java go cs rb; do + if [ "$ext" = "py" ]; then + pattern="^def |^class " + elif [ "$ext" = "js" ] || [ "$ext" = "ts" ]; then + pattern="^function |^class |const.*=.*=>|function.*{$" + else + pattern="^class |^def |^func " + fi + + find . -type f -name "*.$ext" \ + ! -path "*/node_modules/*" \ + ! -path "*/dist/*" \ + ! -path "*/build/*" \ + ! -path "*/.venv/*" \ + ! -path "*/vendor/*" \ + -exec sh -c 'count=$(grep -c "$1" "$2" 2>/dev/null || echo 0); count=${count:-0}; if [ "$count" -gt 20 ]; then echo "$count definitions in $2"; fi' _ "$pattern" {} \; \ + 2>/dev/null || true + done | sort -rn >> /tmp/analysis.md + + cat /tmp/analysis.md + + # Note: GitHub Copilot CLI action is not available as a public action + # Code cleanliness analysis is already performed in the previous step + + - name: Create Issue for Code Cleanliness Review + uses: actions/github-script@main + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const fs = require('fs'); + const analysis = fs.readFileSync('/tmp/analysis.md', 'utf8'); + + const date = new Date().toISOString().split('T')[0]; + const title = `Code Cleanliness Review - ${date}`; + + const body = `# Periodic Code Cleanliness Review + + This is an automated review conducted every 12 hours to maintain code quality. + + ${analysis} + + ## Recommendations + + Please review the analysis above and: + 1. Split large files (>500 lines) into smaller, focused modules + 2. Refactor complex functions into smaller, testable units + 3. Remove code duplication + 4. Ensure consistent code style + 5. Improve code organization and structure + + ## Next Steps + + - Assign this issue to relevant team members + - Create follow-up PRs to address findings + - Document any architectural decisions + + --- + *This issue was automatically generated by the Code Cleanliness Review workflow.* + `; + + // Check if similar issue exists (open, created in last 24 hours) + const issues = await github.rest.issues.listForRepo({ + owner: context.repo.owner, + repo: context.repo.repo, + state: 'open', + labels: ['code-cleanliness', 'automated'], + per_page: 10 + }); + + const recentIssue = issues.data.find(issue => { + const createdAt = new Date(issue.created_at); + const hoursSinceCreation = (Date.now() - createdAt) / (1000 * 60 * 60); + return hoursSinceCreation < 24; + }); + + if (recentIssue) { + console.log(`Recent issue found: #${recentIssue.number}, skipping creation`); + // Update existing issue with new analysis + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: recentIssue.number, + body: `## Updated Analysis (${date})\n\n${analysis}` + }); + } else { + // Create new issue + await github.rest.issues.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title: title, + body: body, + labels: ['code-cleanliness', 'automated', 'needs-review'] + }); + } diff --git a/.github/workflows/auto-copilot-functionality-docs-review.yml b/.github/workflows/auto-copilot-functionality-docs-review.yml new file mode 100644 index 0000000..3ec686a --- /dev/null +++ b/.github/workflows/auto-copilot-functionality-docs-review.yml @@ -0,0 +1,314 @@ +name: "Code Functionality and Documentation Review" + +on: + push: + branches: + - main + - master + pull_request: + types: [opened, synchronize, reopened] + workflow_dispatch: + +permissions: + contents: write + pull-requests: write + issues: write + +jobs: + functionality-check: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@main + + - name: Setup Node.js + uses: actions/setup-node@main + with: + node-version: '20' + continue-on-error: true + + - name: Setup Python + uses: actions/setup-python@main + with: + python-version: '3.11' + continue-on-error: true + + - name: Setup Go + uses: actions/setup-go@main + with: + go-version: 'stable' + continue-on-error: true + + - name: Install Dependencies and Build + id: build + run: | + echo "BUILD_STATUS=unknown" >> $GITHUB_OUTPUT + + # Node.js project + if [ -f "package.json" ]; then + echo "Detected Node.js project" + npm install || echo "npm install failed" + + if grep -q '"build"' package.json; then + npm run build && echo "BUILD_STATUS=success" >> $GITHUB_OUTPUT || echo "BUILD_STATUS=failed" >> $GITHUB_OUTPUT + else + echo "BUILD_STATUS=no-build-script" >> $GITHUB_OUTPUT + fi + fi + + # Python project + if [ -f "requirements.txt" ] || [ -f "setup.py" ] || [ -f "pyproject.toml" ]; then + echo "Detected Python project" + if [ -f "requirements.txt" ]; then + pip install -r requirements.txt || echo "pip install failed" + fi + if [ -f "setup.py" ]; then + pip install -e . || echo "setup.py install failed" + fi + echo "BUILD_STATUS=success" >> $GITHUB_OUTPUT + fi + + # Go project + if [ -f "go.mod" ]; then + echo "Detected Go project" + go build ./... && echo "BUILD_STATUS=success" >> $GITHUB_OUTPUT || echo "BUILD_STATUS=failed" >> $GITHUB_OUTPUT + fi + + # Java/Maven project + if [ -f "pom.xml" ]; then + echo "Detected Maven project" + mvn clean compile && echo "BUILD_STATUS=success" >> $GITHUB_OUTPUT || echo "BUILD_STATUS=failed" >> $GITHUB_OUTPUT + fi + + # Gradle project + if [ -f "build.gradle" ] || [ -f "build.gradle.kts" ]; then + echo "Detected Gradle project" + ./gradlew build -x test && echo "BUILD_STATUS=success" >> $GITHUB_OUTPUT || echo "BUILD_STATUS=failed" >> $GITHUB_OUTPUT + fi + continue-on-error: true + + - name: Run Basic Functionality Tests + run: | + # Try to run tests if they exist + if [ -f "package.json" ] && grep -q '"test"' package.json; then + npm test || echo "Tests failed or not configured" + fi + + if [ -f "pytest.ini" ] || [ -d "tests" ]; then + pytest || echo "Pytest tests failed or not configured" + fi + + if [ -f "go.mod" ]; then + go test ./... || echo "Go tests failed or not configured" + fi + continue-on-error: true + + documentation-review: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@main + + - name: Analyze Documentation + id: doc-analysis + run: | + echo "## Documentation Analysis" > /tmp/doc-analysis.md + echo "" >> /tmp/doc-analysis.md + + # Check for main documentation files + echo "### Main Documentation Files:" >> /tmp/doc-analysis.md + for doc in README.md CONTRIBUTING.md LICENSE.md CHANGELOG.md CODE_OF_CONDUCT.md SECURITY.md; do + if [ -f "$doc" ]; then + echo "✅ $doc exists" >> /tmp/doc-analysis.md + else + echo "❌ $doc is missing" >> /tmp/doc-analysis.md + fi + done + + echo "" >> /tmp/doc-analysis.md + echo "### README.md Quality Check:" >> /tmp/doc-analysis.md + + if [ -f "README.md" ]; then + word_count=$(wc -w < README.md) + echo "- Word count: $word_count" >> /tmp/doc-analysis.md + + if [ $word_count -lt 50 ]; then + echo "⚠️ README.md is very short (< 50 words)" >> /tmp/doc-analysis.md + else + echo "✅ README.md has adequate content" >> /tmp/doc-analysis.md + fi + + # Check for common sections + for section in "Installation" "Usage" "Features" "Contributing" "License" "Documentation"; do + if grep -qi "$section" README.md; then + echo "✅ Contains '$section' section" >> /tmp/doc-analysis.md + else + echo "⚠️ Missing '$section' section" >> /tmp/doc-analysis.md + fi + done + else + echo "❌ README.md does not exist" >> /tmp/doc-analysis.md + fi + + echo "" >> /tmp/doc-analysis.md + echo "### Additional Documentation:" >> /tmp/doc-analysis.md + + # Find all markdown files + find . -name "*.md" \ + ! -path "*/node_modules/*" \ + ! -path "*/.venv/*" \ + ! -path "*/vendor/*" \ + -type f | while read -r file; do + echo "- $file" >> /tmp/doc-analysis.md + done || echo "No additional markdown files found" >> /tmp/doc-analysis.md + + echo "" >> /tmp/doc-analysis.md + echo "### Code with Missing Documentation:" >> /tmp/doc-analysis.md + + # Check for undocumented functions/classes (basic heuristic) + # Python + if find . -name "*.py" ! -path "*/.venv/*" ! -path "*/node_modules/*" | grep -q .; then + echo "" >> /tmp/doc-analysis.md + echo "#### Python files:" >> /tmp/doc-analysis.md + find . -name "*.py" \ + ! -path "*/.venv/*" \ + ! -path "*/node_modules/*" \ + ! -path "*/dist/*" \ + ! -name "__init__.py" \ + -type f | while read -r file; do + # Count functions and classes + func_count=$(grep -c "^def " "$file" 2>/dev/null || echo 0) + class_count=$(grep -c "^class " "$file" 2>/dev/null || echo 0) + docstring_count=$(grep -c '"""' "$file" 2>/dev/null || echo 0) + + # Ensure variables are numeric + func_count=${func_count:-0} + class_count=${class_count:-0} + docstring_count=${docstring_count:-0} + + total=$((func_count + class_count)) + if [ $total -gt 0 ] && [ $docstring_count -eq 0 ]; then + echo "⚠️ $file: $total definitions, no docstrings" >> /tmp/doc-analysis.md + fi + done + fi + + # JavaScript/TypeScript + if find . \( -name "*.js" -o -name "*.ts" \) ! -path "*/node_modules/*" ! -path "*/dist/*" | grep -q .; then + echo "" >> /tmp/doc-analysis.md + echo "#### JavaScript/TypeScript files:" >> /tmp/doc-analysis.md + find . \( -name "*.js" -o -name "*.ts" \) \ + ! -path "*/node_modules/*" \ + ! -path "*/dist/*" \ + ! -path "*/build/*" \ + -type f | while read -r file; do + # Count functions and classes + func_count=$(grep -cE "(^function |^export function |^const .* = .*=>)" "$file" 2>/dev/null || echo 0) + class_count=$(grep -c "^class " "$file" 2>/dev/null || echo 0) + jsdoc_count=$(grep -c '/\*\*' "$file" 2>/dev/null || echo 0) + + # Ensure variables are numeric + func_count=${func_count:-0} + class_count=${class_count:-0} + jsdoc_count=${jsdoc_count:-0} + + total=$((func_count + class_count)) + if [ $total -gt 5 ] && [ $jsdoc_count -eq 0 ]; then + echo "⚠️ $file: ~$total definitions, no JSDoc comments" >> /tmp/doc-analysis.md + fi + done + fi + + cat /tmp/doc-analysis.md + + # Note: GitHub Copilot CLI actions are not available as a public action + # The documentation analysis is already performed in the previous step + + - name: Create Documentation Review Report + uses: actions/github-script@main + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const fs = require('fs'); + const analysis = fs.readFileSync('/tmp/doc-analysis.md', 'utf8'); + + const date = new Date().toISOString().split('T')[0]; + const title = `Code Functionality & Documentation Review - ${date}`; + + const buildStatus = process.env.BUILD_STATUS || 'unknown'; + const buildEmoji = buildStatus === 'success' ? '✅' : + buildStatus === 'failed' ? '❌' : '⚠️'; + + const body = `# Code Functionality and Documentation Review + + ## Build Status: ${buildEmoji} ${buildStatus} + + ${analysis} + + ## Functionality Review + + - Build status: ${buildStatus} + - Tests execution: See workflow logs for details + + ## Recommendations + + ### Documentation: + 1. **Complete README.md** with all required sections + 2. **Add missing documentation files** (CONTRIBUTING.md, CHANGELOG.md, etc.) + 3. **Document all public APIs** and exported functions + 4. **Add inline code comments** for complex logic + 5. **Create usage examples** and tutorials + 6. **Update outdated documentation** to match current code + + ### Functionality: + 1. **Ensure code builds successfully** in CI environment + 2. **Fix any broken functionality** identified in tests + 3. **Add error handling** and validation + 4. **Verify all features work as documented** + + ## Action Items + + - [ ] Add/update missing documentation files + - [ ] Improve README.md quality and completeness + - [ ] Add code comments and docstrings + - [ ] Fix build issues if any + - [ ] Verify all features are documented + + --- + *This issue was automatically generated by the Functionality & Documentation Review workflow.* + `; + + // Check for existing issues + const issues = await github.rest.issues.listForRepo({ + owner: context.repo.owner, + repo: context.repo.repo, + state: 'open', + labels: ['documentation', 'automated'], + per_page: 10 + }); + + const recentIssue = issues.data.find(issue => { + const createdAt = new Date(issue.created_at); + const daysSinceCreation = (Date.now() - createdAt) / (1000 * 60 * 60 * 24); + return daysSinceCreation < 7; + }); + + if (recentIssue) { + console.log(`Recent issue found: #${recentIssue.number}, updating`); + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: recentIssue.number, + body: `## Updated Analysis (${date})\n\nBuild Status: ${buildEmoji} ${buildStatus}\n\n${analysis}` + }); + } else { + await github.rest.issues.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title: title, + body: body, + labels: ['documentation', 'functionality', 'automated', 'needs-review'] + }); + } + env: + BUILD_STATUS: ${{ steps.build.outputs.BUILD_STATUS }} diff --git a/.github/workflows/auto-copilot-org-playwright-loop.yaml b/.github/workflows/auto-copilot-org-playwright-loop.yaml new file mode 100644 index 0000000..63afdad --- /dev/null +++ b/.github/workflows/auto-copilot-org-playwright-loop.yaml @@ -0,0 +1,64 @@ +name: "Org-wide: Copilot Playwright Test, Review, Auto-fix, PR, Merge" + +on: + push: + branches: + - main + - master + +jobs: + playwright-review-fix: + runs-on: ubuntu-latest + steps: + # Checkout repository code + - name: Checkout code + uses: actions/checkout@main + + # Set up Python (change/add for other stacks!) + - name: Setup Python + uses: actions/setup-python@main + with: + python-version: "3.11" + + # Install dependencies (Python example) + - name: Install dependencies + run: | + pip install -r requirements.txt + pip install pytest playwright pytest-playwright + + # Install Playwright browsers + - name: Install Playwright browsers + run: | + python -m playwright install + + # Run Playwright tests + - name: Run Playwright Tests + run: | + pytest tests/ || exit 1 + continue-on-error: true + + # Note: GitHub Copilot agent actions are not available as public actions + # This step would provide automated PR review + # For now, manual PR review is required + + # Note: GitHub Copilot agent actions are not available as public actions + # This step would automatically fix failing Playwright tests with retry loops + # For now, manual test fixing is required + + # Create PR with fixes (if any) + - name: Create Pull Request for Automated Fixes + uses: peter-evans/create-pull-request@main + with: + branch: "copilot/playwright-fixes" + title: "Copilot: Auto-fix Playwright Tests" + body: "Automated Playwright test fixes by Copilot Agent." + commit-message: "Copilot agent Playwright bugfixes" + continue-on-error: true + + # Automerge PR if passing + - name: Automerge PR if checks pass + uses: pascalgn/automerge-action@main + with: + merge-method: squash + github-token: ${{ secrets.GITHUB_TOKEN }} + continue-on-error: true \ No newline at end of file diff --git a/.github/workflows/auto-copilot-org-playwright-loopv2.yaml b/.github/workflows/auto-copilot-org-playwright-loopv2.yaml new file mode 100644 index 0000000..987a9cf --- /dev/null +++ b/.github/workflows/auto-copilot-org-playwright-loopv2.yaml @@ -0,0 +1,57 @@ +name: "Org-wide: Copilot Playwright Test, Review, Auto-fix, PR, Merge" + +on: + push: + branches: + - main + - master + +jobs: + playwright-review-fix: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@main + + - name: Setup Python + uses: actions/setup-python@main + with: + python-version: "3.11" + + - name: Install dependencies + run: | + pip install -r requirements.txt + pip install pytest playwright pytest-playwright + + - name: Install Playwright browsers + run: | + python -m playwright install + + - name: Run Playwright Tests + run: | + pytest tests/ || exit 1 + continue-on-error: true + + # Note: GitHub Copilot agent actions are not available as public actions + # This step would provide automated PR review + # For now, manual PR review is required + + # Note: GitHub Copilot agent actions are not available as public actions + # This step would automatically fix failing Playwright tests + # For now, manual test fixing is required + + - name: Create Pull Request for Automated Fixes + uses: peter-evans/create-pull-request@main + with: + branch: "copilot/playwright-fixes" + title: "Copilot: Auto-fix Playwright Tests" + body: "Automated Playwright test fixes by Copilot Agent." + commit-message: "Copilot agent Playwright bugfixes" + continue-on-error: true + + - name: Automerge PR if checks pass + uses: pascalgn/automerge-action@main + with: + merge-method: squash + github-token: ${{ secrets.GITHUB_TOKEN }} + continue-on-error: true \ No newline at end of file diff --git a/.github/workflows/auto-copilot-playwright-auto-test.yml b/.github/workflows/auto-copilot-playwright-auto-test.yml new file mode 100644 index 0000000..b9cef57 --- /dev/null +++ b/.github/workflows/auto-copilot-playwright-auto-test.yml @@ -0,0 +1,56 @@ +name: "Copilot: Generate and Run Playwright Tests Until Passing" + +on: + push: + branches: + - main + - master + +jobs: + generate-and-test: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@main + + - name: Setup Python + uses: actions/setup-python@main + with: + python-version: "3.11" + + - name: Install dependencies + run: | + pip install -r requirements.txt + pip install pytest playwright pytest-playwright + + - name: Install Playwright browsers + run: | + python -m playwright install + + # Note: GitHub Copilot agent actions are not available as public actions + # This step would generate Playwright test scripts automatically + # For now, manual test script creation is required + + - name: Run Playwright Tests + run: | + pytest tests/ # Or the path to your Playwright scripts + + # Note: GitHub Copilot agent actions are not available as public actions + # This step would automatically fix failing tests and retry + # For now, manual test fixing is required + + - name: Create PR with passing tests or attempted fixes + uses: peter-evans/create-pull-request@main + with: + branch: "copilot/playwright-auto-tests" + title: "Copilot generated Playwright tests (auto-fixed)" + body: "Automated Playwright test generation/fix by Copilot agent." + commit-message: "Copilot agent Playwright tests and fixes" + continue-on-error: true + + - name: Auto-merge if passing + uses: pascalgn/automerge-action@main + with: + merge-method: squash + github-token: ${{ secrets.GITHUB_TOKEN }} + continue-on-error: true \ No newline at end of file diff --git a/.github/workflows/auto-copilot-test-review-playwright.yml b/.github/workflows/auto-copilot-test-review-playwright.yml new file mode 100644 index 0000000..a85bf80 --- /dev/null +++ b/.github/workflows/auto-copilot-test-review-playwright.yml @@ -0,0 +1,239 @@ +name: "Comprehensive Test Review with Playwright" + +on: + push: + branches: + - main + - master + pull_request: + types: [opened, synchronize, reopened] + workflow_dispatch: + +permissions: + contents: write + pull-requests: write + checks: write + +jobs: + test-review-and-execution: + runs-on: ubuntu-latest + strategy: + matrix: + browser: [chromium, firefox, webkit] + mode: [headed, headless] + steps: + - name: Checkout code + uses: actions/checkout@main + + - name: Setup Node.js + uses: actions/setup-node@main + with: + node-version: '20' + cache: 'npm' + continue-on-error: true + + - name: Setup Python + uses: actions/setup-python@main + with: + python-version: '3.11' + cache: 'pip' + continue-on-error: true + + - name: Install Node.js dependencies + run: | + if [ -f "package.json" ]; then + npm install + npm install -D @playwright/test playwright + fi + continue-on-error: true + + - name: Install Python dependencies + run: | + if [ -f "requirements.txt" ]; then + pip install -r requirements.txt + fi + pip install pytest playwright pytest-playwright + continue-on-error: true + + - name: Install Playwright browsers + run: | + npx playwright install --with-deps ${{ matrix.browser }} || python -m playwright install --with-deps ${{ matrix.browser }} + continue-on-error: true + + - name: Verify Playwright installation + run: | + echo "Checking Playwright installation..." + npx playwright --version || python -m playwright --version || echo "Playwright not installed" + + - name: Run Playwright Tests (Headless) + if: matrix.mode == 'headless' + run: | + if [ -f "playwright.config.ts" ] || [ -f "playwright.config.js" ]; then + npx playwright test --browser=${{ matrix.browser }} + elif [ -d "tests" ] && find tests -name "*test*.py" -o -name "*_test.py" | grep -q .; then + pytest tests/ --browser ${{ matrix.browser }} --headed=false + else + echo "No Playwright tests found - this is OK if not a web project" + fi + env: + CI: true + continue-on-error: true + + - name: Run Playwright Tests (Headed) + if: matrix.mode == 'headed' + run: | + if [ -f "playwright.config.ts" ] || [ -f "playwright.config.js" ]; then + npx playwright test --browser=${{ matrix.browser }} --headed + elif [ -d "tests" ] && find tests -name "*test*.py" -o -name "*_test.py" | grep -q .; then + pytest tests/ --browser ${{ matrix.browser }} --headed=true + else + echo "No Playwright tests found - this is OK if not a web project" + fi + env: + CI: true + DISPLAY: :99 + continue-on-error: true + + - name: Upload Playwright Test Results + uses: actions/upload-artifact@main + if: always() + with: + name: playwright-results-${{ matrix.browser }}-${{ matrix.mode }} + path: | + playwright-report/ + test-results/ + playwright-traces/ + retention-days: 30 + continue-on-error: true + + - name: Upload Playwright Screenshots on Failure + uses: actions/upload-artifact@main + if: failure() + with: + name: playwright-screenshots-${{ matrix.browser }}-${{ matrix.mode }} + path: | + screenshots/ + test-results/**/screenshots/ + retention-days: 7 + continue-on-error: true + + test-coverage-review: + runs-on: ubuntu-latest + needs: test-review-and-execution + steps: + - name: Checkout code + uses: actions/checkout@main + + - name: Analyze Test Coverage + id: coverage + run: | + echo "## Test Coverage Analysis" > /tmp/test-analysis.md + echo "" >> /tmp/test-analysis.md + + # Find test files + echo "### Test Files Found:" >> /tmp/test-analysis.md + find . -type f \( -name "*test*.js" -o -name "*test*.ts" -o -name "*test*.py" -o -name "*spec*.js" -o -name "*spec*.ts" \) \ + ! -path "*/node_modules/*" \ + ! -path "*/dist/*" \ + ! -path "*/.venv/*" \ + -exec echo "- {}" \; >> /tmp/test-analysis.md || echo "No test files found" >> /tmp/test-analysis.md + + echo "" >> /tmp/test-analysis.md + echo "### Source Files Without Tests:" >> /tmp/test-analysis.md + + # Find source files that might need tests + for file in $(find . -type f \( -name "*.js" -o -name "*.ts" -o -name "*.py" \) \ + ! -path "*/node_modules/*" \ + ! -path "*/dist/*" \ + ! -path "*/build/*" \ + ! -path "*/.venv/*" \ + ! -path "*/vendor/*" \ + ! -name "*test*" \ + ! -name "*spec*"); do + basename=$(basename "$file" | sed 's/\.[^.]*$//') + + # Check if corresponding test file exists + if ! find . -name "*${basename}*test*" -o -name "*${basename}*spec*" 2>/dev/null | grep -q .; then + echo "- $file (no corresponding test found)" >> /tmp/test-analysis.md + fi + done + + cat /tmp/test-analysis.md + + # Note: GitHub Copilot CLI action is not available as a public action + # Test analysis is already performed in the previous step + + - name: Create or Update Test Review Issue + uses: actions/github-script@main + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const fs = require('fs'); + const analysis = fs.readFileSync('/tmp/test-analysis.md', 'utf8'); + + const date = new Date().toISOString().split('T')[0]; + const title = `Test Coverage Review - ${date}`; + + const body = `# Comprehensive Test Review + + This automated review ensures proper test coverage with Playwright for web tests. + + ${analysis} + + ## Playwright Test Status + + ✅ Tests run in multiple browsers: Chromium, Firefox, WebKit + ✅ Tests run in both headed and headless modes + + ## Recommendations + + 1. **Add Playwright tests** for all web-based functionality + 2. **Migrate existing web tests** to Playwright if not already using it + 3. **Add tests** for source files without coverage + 4. **Review test quality** and maintainability + 5. **Fix flaky tests** and timing issues + 6. **Ensure CI/CD integration** for all tests + + ## Action Items + + - [ ] Review files without tests and add coverage + - [ ] Migrate non-Playwright web tests to Playwright + - [ ] Fix any failing tests + - [ ] Add documentation for test setup and execution + + --- + *This issue was automatically generated by the Test Review workflow.* + `; + + // Check if similar issue exists + const issues = await github.rest.issues.listForRepo({ + owner: context.repo.owner, + repo: context.repo.repo, + state: 'open', + labels: ['test-coverage', 'automated'], + per_page: 10 + }); + + const recentIssue = issues.data.find(issue => { + const createdAt = new Date(issue.created_at); + const daysSinceCreation = (Date.now() - createdAt) / (1000 * 60 * 60 * 24); + return daysSinceCreation < 7; + }); + + if (recentIssue) { + console.log(`Recent issue found: #${recentIssue.number}, updating`); + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: recentIssue.number, + body: `## Updated Analysis (${date})\n\n${analysis}` + }); + } else { + await github.rest.issues.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title: title, + body: body, + labels: ['test-coverage', 'automated', 'playwright', 'needs-review'] + }); + } diff --git a/.github/workflows/auto-label-comment-prs.yml b/.github/workflows/auto-label-comment-prs.yml new file mode 100644 index 0000000..51067fb --- /dev/null +++ b/.github/workflows/auto-label-comment-prs.yml @@ -0,0 +1,41 @@ +name: "Label PRs and auto-comment" +on: + pull_request: + types: [opened, reopened, synchronize] +jobs: + pr_label_comment: + runs-on: ubuntu-latest + steps: + - uses: actions/github-script@main + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const pr_number = context.payload.pull_request.number; + + // Add label + try { + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr_number, + labels: ["needs-review", "copilot"] // <-- TUNE ME + }); + console.log(`✅ Added labels to PR #${pr_number}`); + } catch (error) { + console.log(`⚠️ Failed to add labels: ${error.message}`); + console.log("Note: This may be due to insufficient permissions or invalid label names."); + } + + // Add automated comment + try { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr_number, + body: "Thanks for the PR! Copilot will assist with review." + }); + console.log(`✅ Added comment to PR #${pr_number}`); + } catch (error) { + console.log(`⚠️ Failed to add comment: ${error.message}`); + console.log("Note: This may be due to insufficient permissions."); + } \ No newline at end of file diff --git a/.github/workflows/auto-label.yml b/.github/workflows/auto-label.yml new file mode 100644 index 0000000..768aae7 --- /dev/null +++ b/.github/workflows/auto-label.yml @@ -0,0 +1,33 @@ +# Auto-label new issues with your default labels! +# Set or add labels in the 'labels' list. + +name: Auto Label New Issues + +on: + issues: + types: [opened] + +jobs: + label: + runs-on: ubuntu-latest + steps: + - name: Add labels + uses: actions/github-script@main + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + // Add or tweak your labels here + const labels = ["triage", "copilot"]; // <-- TUNE ME! + + try { + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + labels + }); + console.log(`✅ Added labels [${labels.join(", ")}] to issue #${context.issue.number}`); + } catch (error) { + console.log(`⚠️ Failed to add labels: ${error.message}`); + console.log("Note: This may be due to insufficient permissions or invalid label names."); + } \ No newline at end of file diff --git a/check_issues.sh b/check_issues.sh new file mode 100644 index 0000000..1c393f9 --- /dev/null +++ b/check_issues.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +echo "=== Searching for remaining shell arithmetic operations ===" +grep -r '\$((.*))' .github/workflows/ || echo "No shell arithmetic found" + +echo "" +echo "=== Searching for remaining GitHub Copilot actions ===" +grep -r 'github/copilot' .github/workflows/ || echo "No GitHub Copilot actions found" + +echo "" +echo "=== Searching for remaining shell arithmetic patterns ===" +grep -r '\$(' .github/workflows/ | grep -E '(count|total).*=' || echo "No problematic patterns found" + +echo "" +echo "=== Checking for any uses: statements with copilot ===" +grep -r 'uses:.*copilot' .github/workflows/ || echo "No copilot uses statements found" \ No newline at end of file diff --git a/IMPLEMENTATION.md b/docs/implementation.md similarity index 98% rename from IMPLEMENTATION.md rename to docs/implementation.md index 65ab3d3..6c38874 100644 --- a/IMPLEMENTATION.md +++ b/docs/implementation.md @@ -1,4 +1,4 @@ -# Implementation Summary: I/O and Multiplexing Support +# Implementation Design Document: I/O and Multiplexing Support This document summarizes the implementation of I/O capabilities and JSON-RPC framing with command multiplexing for the Chrome DevTools Protocol library. @@ -181,4 +181,4 @@ This implementation successfully adds I/O capabilities and command multiplexing - ✅ Documentation (README, guide, examples) - ✅ Backward compatibility (100%) -The implementation fulfills the issue requirements: "Add some IO up in this thing. Add support for the JSON RPC framing (if it's still a thing) AND multiplexing commands. Multiplex so much you can't plex any more." ✅ +The implementation fulfills the issue requirements: "Add some IO up in this thing. Add support for the JSON RPC framing (if it's still a thing) AND multiplexing commands. Multiplex so much you can't plex any more." ✅ \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index c4ba5e6..e9b97d8 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -11,6 +11,7 @@ Python wrappers for Chrome DevTools Protocol (CDP). overview getting_started + connection api develop changelog