chore: get rid of old nodes tables #39
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Quality Checks | |
| on: | |
| pull_request: | |
| branches: ['**'] | |
| push: | |
| branches: [main] | |
| jobs: | |
| e2e_tests: | |
| name: Playwright Tests | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| services: | |
| backend: | |
| image: ghcr.io/ydb-platform/local-ydb:nightly | |
| ports: | |
| - 2135:2135 | |
| - 8765:8765 | |
| options: --hostname localhost -e YDB_ALLOW_ORIGIN="http://localhost:3000" | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 18 | |
| cache: npm | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Install Playwright deps | |
| run: npm run test:e2e:install | |
| - name: Run Playwright tests | |
| id: run_tests | |
| run: npm run test:e2e | |
| env: | |
| CI: true | |
| PLAYWRIGHT_VIDEO: 'on' | |
| - name: Upload Playwright artifacts | |
| if: always() | |
| uses: actions/upload-artifact@v3 | |
| with: | |
| name: playwright-artifacts | |
| path: playwright-artifacts | |
| retention-days: 5 | |
| - name: Get test results | |
| if: always() | |
| id: test-results | |
| run: | | |
| echo "Current directory: $(pwd)" | |
| echo "Listing playwright-artifacts directory:" | |
| ls -R playwright-artifacts | |
| if [ -f "playwright-artifacts/test-results.json" ]; then | |
| echo "Parsing JSON file:" | |
| total=$(jq '.stats.expected + .stats.unexpected + .stats.flaky + .stats.skipped' playwright-artifacts/test-results.json) | |
| passed=$(jq '.stats.expected' playwright-artifacts/test-results.json) | |
| failed=$(jq '.stats.unexpected' playwright-artifacts/test-results.json) | |
| flaky=$(jq '.stats.flaky' playwright-artifacts/test-results.json) | |
| skipped=$(jq '.stats.skipped' playwright-artifacts/test-results.json) | |
| echo "Parsed values:" | |
| echo "Total: $total" | |
| echo "Passed: $passed" | |
| echo "Failed: $failed" | |
| echo "Flaky: $flaky" | |
| echo "Skipped: $skipped" | |
| else | |
| echo "test-results.json file not found" | |
| total=0 | |
| passed=0 | |
| failed=0 | |
| flaky=0 | |
| skipped=0 | |
| fi | |
| echo "total=$total" >> $GITHUB_OUTPUT | |
| echo "passed=$passed" >> $GITHUB_OUTPUT | |
| echo "failed=$failed" >> $GITHUB_OUTPUT | |
| echo "flaky=$flaky" >> $GITHUB_OUTPUT | |
| echo "skipped=$skipped" >> $GITHUB_OUTPUT | |
| bundle_size: | |
| name: Check Bundle Size | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'pull_request' | |
| outputs: | |
| current_size: ${{ steps.current_size.outputs.size }} | |
| main_size: ${{ steps.main_size.outputs.size }} | |
| diff: ${{ steps.size_diff.outputs.diff }} | |
| percent: ${{ steps.size_diff.outputs.percent }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 18 | |
| cache: npm | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Build bundle (current branch) | |
| run: npm run build | |
| - name: Get current bundle size | |
| id: current_size | |
| run: | | |
| size=$(du -sb build | cut -f1) | |
| echo "size=$size" >> $GITHUB_OUTPUT | |
| - name: Checkout main branch | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: main | |
| - name: Install dependencies (main) | |
| run: npm ci | |
| - name: Build bundle (main branch) | |
| run: npm run build | |
| - name: Get main bundle size | |
| id: main_size | |
| run: | | |
| size=$(du -sb build | cut -f1) | |
| echo "size=$size" >> $GITHUB_OUTPUT | |
| - name: Calculate size difference | |
| id: size_diff | |
| run: | | |
| current=${{ steps.current_size.outputs.size }} | |
| main=${{ steps.main_size.outputs.size }} | |
| diff=$((current - main)) | |
| if [ "$main" -ne "0" ]; then | |
| percent=$(awk "BEGIN {printf \"%.2f\", ($diff/$main) * 100}") | |
| else | |
| percent="N/A" | |
| fi | |
| echo "diff=$diff" >> $GITHUB_OUTPUT | |
| echo "percent=$percent" >> $GITHUB_OUTPUT | |
| deploy_report: | |
| name: Deploy Test Report | |
| needs: [e2e_tests] | |
| if: always() && (github.event_name == 'push' && github.ref == 'refs/heads/main' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository)) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| pages: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Fetch gh-pages branch | |
| run: | | |
| git fetch origin gh-pages:gh-pages | |
| mkdir gh-pages | |
| git --work-tree=gh-pages checkout gh-pages -- . | |
| - name: Download Playwright artifacts | |
| uses: actions/download-artifact@v3 | |
| with: | |
| name: playwright-artifacts | |
| path: playwright-artifacts | |
| - name: Copy new report | |
| run: | | |
| if [ "${{ github.event_name }}" = "pull_request" ]; then | |
| REPORT_DIR="${{ github.event.pull_request.number }}" | |
| else | |
| REPORT_DIR="main" | |
| fi | |
| rm -rf gh-pages/$REPORT_DIR | |
| mkdir -p gh-pages/$REPORT_DIR | |
| cp -r playwright-artifacts/playwright-report/* gh-pages/$REPORT_DIR/ | |
| # Also copy test-results.json if it exists | |
| if [ -f "playwright-artifacts/test-results.json" ]; then | |
| cp playwright-artifacts/test-results.json gh-pages/$REPORT_DIR/ | |
| fi | |
| - name: Deploy report to GitHub Pages | |
| uses: peaceiris/actions-gh-pages@v3 | |
| with: | |
| github_token: ${{ secrets.GITHUB_TOKEN }} | |
| publish_dir: gh-pages | |
| destination_dir: . | |
| force_orphan: true | |
| update_pr: | |
| name: Update PR Description | |
| needs: [e2e_tests, bundle_size] | |
| if: always() && github.event_name == 'pull_request' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| pull-requests: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Download Playwright artifacts | |
| uses: actions/download-artifact@v3 | |
| with: | |
| name: playwright-artifacts | |
| path: playwright-artifacts | |
| - name: Fetch gh-pages branch | |
| run: | | |
| git fetch origin gh-pages:gh-pages | |
| mkdir gh-pages | |
| git --work-tree=gh-pages checkout gh-pages -- . | |
| - name: Update PR description | |
| uses: actions/github-script@v6 | |
| with: | |
| github-token: ${{secrets.GITHUB_TOKEN}} | |
| script: | | |
| const fs = require('fs'); | |
| const testResultsPath = 'playwright-artifacts/test-results.json'; | |
| const mainTestResultsPath = 'gh-pages/main/test-results.json'; | |
| let testResults; | |
| let mainTestResults; | |
| let testComparison = { | |
| new: [], | |
| skipped: [], | |
| deleted: [] | |
| }; | |
| // Helper function to extract all tests from a suite recursively | |
| function extractTestsFromSuite(suite, parentTitle = '') { | |
| let tests = []; | |
| const fullSuiteTitle = parentTitle ? `${parentTitle} > ${suite.title}` : suite.title; | |
| // Add tests from specs | |
| if (suite.specs) { | |
| tests.push(...suite.specs.map(spec => ({ | |
| title: spec.title, | |
| fullTitle: `${fullSuiteTitle} > ${spec.title}`, | |
| status: spec.ok ? 'passed' : spec.skipped ? 'skipped' : 'failed', | |
| file: suite.file, | |
| skipped: spec.skipped || false | |
| }))); | |
| } | |
| // Recursively process nested suites | |
| if (suite.suites) { | |
| suite.suites.forEach(nestedSuite => { | |
| tests.push(...extractTestsFromSuite(nestedSuite, fullSuiteTitle)); | |
| }); | |
| } | |
| return tests; | |
| } | |
| // Read current PR test results | |
| if (fs.existsSync(testResultsPath)) { | |
| const rawData = fs.readFileSync(testResultsPath); | |
| const data = JSON.parse(rawData); | |
| const allTests = data.suites.flatMap(suite => extractTestsFromSuite(suite)); | |
| testResults = { | |
| total: data.stats.expected + data.stats.unexpected + data.stats.flaky + data.stats.skipped, | |
| passed: data.stats.expected, | |
| failed: data.stats.unexpected, | |
| flaky: data.stats.flaky, | |
| skipped: data.stats.skipped, | |
| tests: allTests | |
| }; | |
| } else { | |
| console.log('Test results file not found'); | |
| testResults = { total: 0, passed: 0, failed: 0, flaky: 0, skipped: 0, tests: [] }; | |
| } | |
| // Read main branch test results | |
| if (fs.existsSync(mainTestResultsPath)) { | |
| const rawData = fs.readFileSync(mainTestResultsPath); | |
| const data = JSON.parse(rawData); | |
| const allTests = data.suites.flatMap(suite => extractTestsFromSuite(suite)); | |
| mainTestResults = { tests: allTests }; | |
| // Compare tests | |
| const currentTests = new Map(testResults.tests.map(t => [t.fullTitle, t])); | |
| const mainTests = new Map(mainTestResults.tests.map(t => [t.fullTitle, t])); | |
| // Find new tests | |
| for (const [fullTitle, test] of currentTests) { | |
| if (!mainTests.has(fullTitle)) { | |
| testComparison.new.push(`${test.title} (${test.file})`); | |
| } | |
| } | |
| // Find deleted tests | |
| for (const [fullTitle, test] of mainTests) { | |
| if (!currentTests.has(fullTitle)) { | |
| testComparison.deleted.push(`${test.title} (${test.file})`); | |
| } | |
| } | |
| // Find skipped tests (both newly skipped and already skipped) | |
| for (const [fullTitle, test] of currentTests) { | |
| if (test.skipped) { | |
| testComparison.skipped.push(`${test.title} (${test.file})`); | |
| } | |
| } | |
| } else { | |
| console.log('Main branch test results file not found'); | |
| mainTestResults = { tests: [] }; | |
| } | |
| const reportUrl = `https://${context.repo.owner}.github.io/${context.repo.repo}/${context.issue.number}/`; | |
| const status = testResults.failed > 0 ? '❌ FAILED' : (testResults.flaky > 0 ? '⚠️ FLAKY' : '✅ PASSED'); | |
| const statusColor = testResults.failed > 0 ? 'red' : (testResults.flaky > 0 ? 'orange' : 'green'); | |
| const currentSize = parseInt('${{ needs.bundle_size.outputs.current_size }}'); | |
| const mainSize = parseInt('${{ needs.bundle_size.outputs.main_size }}'); | |
| const diff = parseInt('${{ needs.bundle_size.outputs.diff }}'); | |
| const percent = '${{ needs.bundle_size.outputs.percent }}'; | |
| const formatSize = (size) => { | |
| if (size >= 1024) { | |
| return `${(size / (1024 * 1024)).toFixed(2)} MB`; | |
| } | |
| return `${(size / 1024).toFixed(2)} KB`; | |
| }; | |
| const bundleStatus = percent === 'N/A' ? '⚠️' : | |
| parseFloat(percent) > 0 ? '🔺' : | |
| parseFloat(percent) < 0 ? '🔽' : '✅'; | |
| const ciSection = `## CI Results | |
| ### Test Status: <span style="color: ${statusColor};">${status}</span> | |
| 📊 [Full Report](${reportUrl}) | |
| | Total | Passed | Failed | Flaky | Skipped | | |
| |:-----:|:------:|:------:|:-----:|:-------:| | |
| | ${testResults.total} | ${testResults.passed} | ${testResults.failed} | ${testResults.flaky} | ${testResults.skipped} | | |
| <details> | |
| <summary>Test Changes Summary ✨(${testComparison.new.length}) ⏭️(${testResults.skipped}) 🗑️(${testComparison.deleted.length})</summary> | |
| #### ✨ New Tests (${testComparison.new.length}) | |
| ${testComparison.new.length > 0 ? testComparison.new.map((test, i) => `${i + 1}. ${test}`).join('\n') : 'None'} | |
| #### ⏭️ Skipped Tests (${testResults.skipped}) | |
| ${testResults.tests.filter(t => t.skipped).map((test, i) => `${i + 1}. ${test.title} (${test.file})`).join('\n') || 'None'} | |
| #### 🗑️ Deleted Tests (${testComparison.deleted.length}) | |
| ${testComparison.deleted.length > 0 ? testComparison.deleted.map((test, i) => `${i + 1}. ${test}`).join('\n') : 'None'} | |
| </details> | |
| ### Bundle Size: ${bundleStatus} | |
| Current: ${formatSize(currentSize)} | Main: ${formatSize(mainSize)} | |
| Diff: ${diff > 0 ? '+' : ''}${formatSize(Math.abs(diff))} (${percent === 'N/A' ? 'N/A' : `${percent}%`}) | |
| ${ | |
| percent === 'N/A' ? '⚠️ Unable to calculate change.' : | |
| parseFloat(percent) > 0 ? '⚠️ Bundle size increased. Please review.' : | |
| parseFloat(percent) < 0 ? '✅ Bundle size decreased.' : '✅ Bundle size unchanged.' | |
| } | |
| <details> | |
| <summary>ℹ️ CI Information</summary> | |
| - Test recordings for failed tests are available in the full report. | |
| - Bundle size is measured for the entire 'dist' directory. | |
| - 📊 indicates links to detailed reports. | |
| - 🔺 indicates increase, 🔽 decrease, and ✅ no change in bundle size. | |
| </details>`; | |
| const { data: pullRequest } = await github.rest.pulls.get({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: context.issue.number, | |
| }); | |
| const currentBody = pullRequest.body || ''; | |
| const ciSectionRegex = /## CI Results[\s\S]*?(?=\n## (?!CI Results)|$)/; | |
| let newBody = currentBody; | |
| if (ciSectionRegex.test(newBody)) { | |
| newBody = newBody.replace(ciSectionRegex, ciSection); | |
| } else { | |
| newBody += '\n\n' + ciSection; | |
| } | |
| await github.rest.pulls.update({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: context.issue.number, | |
| body: newBody, | |
| }); |