chore(deps): bump lodash from 4.17.21 to 4.17.23 #895
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: Build and Test Pipeline | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| checks: write | |
| actions: read | |
| statuses: write | |
| deployments: write | |
| issues: write | |
| discussions: write | |
| on: | |
| push: | |
| branches: | |
| - master | |
| paths: | |
| - 'src/**' | |
| - 'test/**' | |
| - 'package.json' | |
| - 'package-lock.json' | |
| - 'tsconfig.json' | |
| - 'vitest.config.ts' | |
| - 'playwright.config.ts' | |
| - 'rollup.config.mjs' | |
| - '.github/workflows/main.yml' | |
| pull_request: | |
| branches: | |
| - master | |
| paths: | |
| - 'src/**' | |
| - 'test/**' | |
| - 'package.json' | |
| - 'package-lock.json' | |
| - 'tsconfig.json' | |
| - 'vitest.config.ts' | |
| - 'playwright.config.ts' | |
| - 'rollup.config.mjs' | |
| - '.github/workflows/main.yml' | |
| workflow_dispatch: | |
| jobs: | |
| guard-dist: | |
| name: Reject PRs changing dist/ | |
| if: github.event_name == 'pull_request' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Fail if PR modifies files in dist/ | |
| uses: actions/github-script@v8 | |
| with: | |
| script: | | |
| const pr = context.payload.pull_request; | |
| const { owner, repo } = context.repo; | |
| const files = await github.paginate( | |
| github.rest.pulls.listFiles, | |
| { owner, repo, pull_number: pr.number, per_page: 100 } | |
| ); | |
| const changedInDist = files.filter(f => { | |
| const cur = f.filename?.startsWith('dist/'); | |
| const prev = f.previous_filename?.startsWith?.('dist/'); | |
| return cur || prev; | |
| }); | |
| if (changedInDist.length) { | |
| const list = changedInDist.map(f => `- ${f.status}: ${f.filename}`).join('\n'); | |
| core.setFailed(`Changes in dist/ are not allowed in PRs.\n${list}`); | |
| } | |
| build-and-unit: | |
| name: Build & Unit Tests | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 20 | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: npm install | |
| - name: Create directories | |
| run: mkdir -p reports dist docs test-results coverage/unit coverage/e2e coverage/merged | |
| - name: Run unit tests with Vitest (coverage + JUnit) | |
| run: npx vitest run --coverage --reporter=default --reporter=junit --outputFile=test-report.junit.xml | |
| - name: Upload coverage reports to Codecov | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/master' | |
| uses: codecov/codecov-action@v5 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| - name: Upload test results to Codecov | |
| if: ${{ !cancelled() && github.event_name == 'push' && github.ref == 'refs/heads/master' }} | |
| uses: codecov/codecov-action@v5 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| report_type: test_results | |
| files: test-report.junit.xml | |
| - name: 'Report Coverage' | |
| if: always() | |
| uses: davelosert/vitest-coverage-report-action@v2 | |
| with: | |
| json-summary-path: './coverage/unit/coverage-summary.json' | |
| json-final-path: './coverage/unit/coverage-final.json' | |
| - name: Build (prod) | |
| run: npm run build:all:prod | |
| - name: Run ESLint | |
| run: | | |
| ./node_modules/.bin/eslint ./src --format junit --output-file ./reports/eslint/eslint.xml | |
| - name: Code complexity analysis | |
| run: | | |
| mkdir -p reports/complexity | |
| ./node_modules/.bin/eslint ./src --config eslint.config.js --rule 'complexity/complexity: ["error", { max: 15 }]' --format json > reports/complexity/complexity-report.json || true | |
| echo "Complexity report generated at reports/complexity/complexity-report.json" | |
| - name: TypeScript type checking | |
| run: npx tsc --noEmit | |
| - name: Dependency vulnerability scanning | |
| run: npm audit --level=moderate | |
| # Upload build artifacts for integration tests | |
| - name: Upload build artifacts | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: build-output | |
| path: | | |
| dist/ | |
| coverage/unit/ | |
| retention-days: 1 | |
| integration-tests: | |
| name: Integration (${{ matrix.browser }}, Shard ${{ matrix.shard }}/4) | |
| needs: build-and-unit | |
| if: github.actor != 'dependabot[bot]' | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| browser: [chromium, firefox] | |
| shard: [ 1, 2, 3, 4 ] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 20 | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: npm install | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@v7 | |
| with: | |
| name: build-output | |
| # Cache Playwright browsers | |
| - name: Cache Playwright browsers | |
| uses: actions/cache@v5 | |
| id: playwright-cache | |
| with: | |
| path: ~/.cache/ms-playwright | |
| key: playwright-${{ runner.os }}-${{ matrix.browser }}-${{ hashFiles('package-lock.json') }} | |
| - name: Install Playwright browser | |
| if: steps.playwright-cache.outputs.cache-hit != 'true' | |
| run: npx playwright install --with-deps ${{ matrix.browser }} | |
| - name: Install Playwright deps only | |
| if: steps.playwright-cache.outputs.cache-hit == 'true' | |
| run: npx playwright install-deps ${{ matrix.browser }} | |
| - name: Create coverage directories | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/master' | |
| run: mkdir -p coverage/e2e/shard-${{ matrix.shard }} | |
| - name: Run integration tests (${{ matrix.browser }}, shard ${{ matrix.shard }}/4) | |
| env: | |
| COVERAGE: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && matrix.browser == 'chromium' && 'true' || 'false' }} | |
| SHARD_INDEX: ${{ matrix.shard }} | |
| run: npx playwright test --project=${{ matrix.browser }} --shard=${{ matrix.shard }}/4 | |
| - name: Upload test results | |
| if: always() | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: playwright-results-${{ matrix.browser }}-shard-${{ matrix.shard }} | |
| path: test-results/ | |
| retention-days: 7 | |
| if-no-files-found: ignore | |
| - name: Upload coverage artifact | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/master' && matrix.browser == 'chromium' | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: coverage-shard-${{ matrix.shard }} | |
| path: coverage/e2e/shard-${{ matrix.shard }}/ | |
| retention-days: 1 | |
| # Merge coverage from all shards - runs only on master after integration tests complete | |
| merge-integration-coverage: | |
| name: Merge Coverage Reports | |
| needs: [ build-and-unit, integration-tests ] | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/master' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 20 | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: npm install | |
| - name: Download unit test coverage | |
| uses: actions/download-artifact@v7 | |
| with: | |
| name: build-output | |
| path: . | |
| - name: Create coverage directories | |
| run: mkdir -p coverage/e2e coverage/merged | |
| - name: Download coverage shard 1 | |
| uses: actions/download-artifact@v7 | |
| with: | |
| name: coverage-shard-1 | |
| path: coverage/e2e/shard-1 | |
| - name: Download coverage shard 2 | |
| uses: actions/download-artifact@v7 | |
| with: | |
| name: coverage-shard-2 | |
| path: coverage/e2e/shard-2 | |
| - name: Download coverage shard 3 | |
| uses: actions/download-artifact@v7 | |
| with: | |
| name: coverage-shard-3 | |
| path: coverage/e2e/shard-3 | |
| - name: Download coverage shard 4 | |
| uses: actions/download-artifact@v7 | |
| with: | |
| name: coverage-shard-4 | |
| path: coverage/e2e/shard-4 | |
| - name: List coverage files | |
| run: | | |
| echo "Unit coverage:" | |
| ls -la coverage/unit/ || echo "No unit coverage" | |
| echo "E2E coverage shards:" | |
| ls -laR coverage/e2e/ || echo "No e2e coverage" | |
| - name: Merge coverage reports | |
| run: npx tsx scripts/merge-coverage.ts | |
| - name: Upload combined coverage to Codecov | |
| uses: codecov/codecov-action@v5 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: ./coverage/merged/lcov.info | |
| flags: combined | |
| name: combined-coverage | |
| - name: Upload combined coverage report | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: combined-coverage-report | |
| path: coverage/merged/ | |
| retention-days: 30 | |
| performance-tests: | |
| name: Performance Tests | |
| needs: build-and-unit | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/master' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 20 | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: npm install | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@v7 | |
| with: | |
| name: build-output | |
| - name: Run performance regression tests | |
| id: performance_test | |
| run: npm run test:performance | |
| continue-on-error: true | |
| - name: Upload performance benchmark results | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: performance-benchmark | |
| path: reports/performance-benchmark.json | |
| retention-days: 30 | |
| - name: Create issue for performance regression | |
| if: steps.performance_test.outcome == 'failure' | |
| uses: actions/github-script@v8 | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| script: | | |
| const fs = require('fs'); | |
| try { | |
| const regressionFile = 'reports/performance-regressions.json'; | |
| if (fs.existsSync(regressionFile)) { | |
| const regressionData = JSON.parse(fs.readFileSync(regressionFile, 'utf8')); | |
| const issue = await github.rest.issues.create({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| title: `🚨 Performance Regression Detected: ${regressionData.summary}`, | |
| body: `## Performance Regression Alert\n\nThe following performance regressions were detected in commit ${context.sha}:\n\n\`\`\`\n${regressionData.details}\n\`\`\`\n\nPlease investigate these regressions and fix them as soon as possible.\n\n[View workflow run](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId})`, | |
| labels: ['bug', 'performance'] | |
| }); | |
| console.log(`Created issue #${issue.data.number}: ${issue.data.title}`); | |
| } else { | |
| console.log('No regression file found, skipping issue creation'); | |
| } | |
| } catch (error) { | |
| console.error('Error creating issue:', error); | |
| } | |
| finalize: | |
| name: Finalize & Commit | |
| needs: [ build-and-unit, integration-tests, merge-integration-coverage, performance-tests ] | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/master' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 20 | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: npm install | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@v7 | |
| with: | |
| name: build-output | |
| - name: Analyze bundle size | |
| run: | | |
| ls -la dist/*.js | awk '{print $5, $9}' > bundle-size.txt | |
| cat bundle-size.txt | |
| - name: Bundle analysis | |
| run: npx @codecov/bundle-analyzer ./dist --bundle-name=scorm-again --upload-token=${{ secrets.CODECOV_TOKEN }} | |
| working-directory: ./ | |
| - name: Format code with Prettier | |
| run: npm run prettier | |
| - name: Commit and Push Changes | |
| uses: stefanzweifel/git-auto-commit-action@v6 | |
| with: | |
| commit_message: "[skip ci] Add changes during build" | |
| file_pattern: "dist" | |
| skip_dirty_check: false |