From f45736c0b633727db9851671dee8ad026825ce2d Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Sun, 6 Jul 2025 22:50:04 -0700 Subject: [PATCH] Try Turborepo (#1304) * Try Turborepo * Add webamp as explicit dependency of docs * Update pnpm lock * Generate types as part of webamp build-library * To many dashes --- .github/workflows/ci.yml | 185 ++++-------------------------- .gitignore | 5 +- README.md | 46 ++++++++ package.json | 9 +- packages/webamp-docs/package.json | 3 +- pnpm-lock.yaml | 67 +++++++++++ turbo.json | 55 +++++++++ 7 files changed, 195 insertions(+), 175 deletions(-) create mode 100644 turbo.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 96a51f86..af3ed292 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,32 +11,9 @@ on: - "LICENSE.txt" jobs: - # Fast job to install dependencies and cache them for other jobs - setup: + # Main CI job - using Turborepo for dependency management + ci: runs-on: ubuntu-latest - outputs: - cache-key: ${{ steps.cache-key.outputs.key }} - steps: - - uses: actions/checkout@v4 - - name: Install pnpm - uses: pnpm/action-setup@v2 - with: - version: 9.12.0 - - name: Generate cache key - id: cache-key - run: echo "key=node-modules-${{ hashFiles('**/pnpm-lock.yaml') }}" >> $GITHUB_OUTPUT - - name: Use Node.js 20.x - uses: actions/setup-node@v4 - with: - node-version: 20.x - cache: "pnpm" - - name: Install Dependencies - run: pnpm install --frozen-lockfile - - # Build job - Vite build for demo site - build: - runs-on: ubuntu-latest - needs: setup steps: - uses: actions/checkout@v4 - name: Install pnpm @@ -50,150 +27,36 @@ jobs: cache: "pnpm" - name: Install Dependencies run: pnpm install --frozen-lockfile - - name: Build Vite Demo + - name: Build all packages run: | - # Set CI environment variable for optimized builds export CI=true - pnpm --filter ani-cursor build - pnpm --filter winamp-eqf build - pnpm --filter webamp build + npx turbo build build-library env: NODE_ENV: production - - name: Cache build artifacts - uses: actions/cache@v4 - with: - path: | - packages/ani-cursor/dist - packages/winamp-eqf/built - packages/webamp/dist - key: build-artifacts-${{ github.sha }} - - # Build Library job - Rollup build for library bundles - build-library: - runs-on: ubuntu-latest - needs: setup - steps: - - uses: actions/checkout@v4 - - name: Install pnpm - uses: pnpm/action-setup@v2 - with: - version: 9.12.0 - - name: Use Node.js 20.x - uses: actions/setup-node@v4 - with: - node-version: 20.x - cache: "pnpm" - - name: Install Dependencies - run: pnpm install --frozen-lockfile - - name: Build Library Bundles + - name: Lint and type-check run: | - # Set CI environment variable for optimized builds - export CI=true - pnpm --filter ani-cursor build - pnpm --filter winamp-eqf build - pnpm --filter webamp build-library - env: - NODE_ENV: production - - name: Cache library artifacts - uses: actions/cache@v4 - with: - path: | - packages/ani-cursor/dist - packages/winamp-eqf/built - packages/webamp/built - key: library-artifacts-${{ github.sha }} - - # Lint job - depends on build-library for type declarations - lint: - runs-on: ubuntu-latest - needs: [setup, build-library] - steps: - - uses: actions/checkout@v4 - - name: Install pnpm - uses: pnpm/action-setup@v2 - with: - version: 9.12.0 - - name: Use Node.js 20.x - uses: actions/setup-node@v4 - with: - node-version: 20.x - cache: "pnpm" - - name: Install Dependencies - run: pnpm install --frozen-lockfile - - name: Restore library artifacts - uses: actions/cache@v4 - with: - path: | - packages/ani-cursor/dist - packages/winamp-eqf/built - packages/webamp/built - key: library-artifacts-${{ github.sha }} - fail-on-cache-miss: true - - name: Lint - run: | - pnpm lint - pnpm type-check - - # Test job - waits for build artifacts - test: - runs-on: ubuntu-latest - needs: [setup, build] - steps: - - uses: actions/checkout@v4 - - name: Install pnpm - uses: pnpm/action-setup@v2 - with: - version: 9.12.0 - - name: Use Node.js 20.x - uses: actions/setup-node@v4 - with: - node-version: 20.x - cache: "pnpm" - - name: Install Dependencies - run: pnpm install --frozen-lockfile - - name: Restore build artifacts - uses: actions/cache@v4 - with: - path: | - packages/ani-cursor/dist - packages/winamp-eqf/built - packages/webamp/dist - key: build-artifacts-${{ github.sha }} - fail-on-cache-miss: true - - name: Run Unit Tests + npx turbo lint type-check + - name: Run tests run: | touch packages/skin-database/config.js - # Run tests with optimizations for CI export CI=true - pnpm test -- --maxWorkers=2 - pnpm --filter webamp test -- --maxWorkers=2 + npx turbo test -- --maxWorkers=2 env: NODE_ENV: test - # - name: Run Integration Tests - # run: yarn workspace webamp integration-tests - # env: - # CI: true - # - name: Upload Screenshot Diffs - # if: failure() - # uses: actions/upload-artifact@v4 - # with: - # name: image_diffs - # path: packages/webamp/js/__tests__/__image_snapshots__/__diff_output__/ - # - name: Generate New Screenshots - # if: failure() - # run: | - # yarn workspace webamp integration-tests -u - # - name: Upload New Screenshots - # if: failure() - # uses: actions/upload-artifact@v4 - # with: - # name: new_images - # path: packages/webamp/js/__tests__/__image_snapshots__/ - main-release: + - name: Cache build artifacts for release + uses: actions/cache@v4 + with: + path: | + packages/ani-cursor/dist + packages/winamp-eqf/built + packages/webamp/dist + key: release-artifacts-${{ github.sha }} + # Release job - publish packages to NPM + release: name: Publish packages to NPM runs-on: ubuntu-latest if: github.event_name == 'push' && github.repository == 'captbaritone/webamp' - needs: [build, build-library, lint, test] + needs: [ci] steps: - uses: actions/checkout@v4 - name: Install pnpm @@ -214,16 +77,8 @@ jobs: packages/ani-cursor/dist packages/winamp-eqf/built packages/webamp/dist - key: build-artifacts-${{ github.sha }} - fail-on-cache-miss: true - - name: Restore library artifacts - uses: actions/cache@v4 - with: - path: | - packages/ani-cursor/dist - packages/winamp-eqf/built packages/webamp/built - key: library-artifacts-${{ github.sha }} + key: release-artifacts-${{ github.sha }} fail-on-cache-miss: true - name: Set version for all packages if: github.ref == 'refs/heads/master' diff --git a/.gitignore b/.gitignore index 33eca0b4..829ecf68 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ node_modules .vscode -dist \ No newline at end of file +dist + +# Turborepo cache +.turbo \ No newline at end of file diff --git a/README.md b/README.md index 1d9e7bdd..2305d1ca 100755 --- a/README.md +++ b/README.md @@ -65,6 +65,52 @@ Nullsoft, the code within this project is released under the [MIT License](LICENSE.txt). That being said, if you do anything interesting with this code, please let me know. I'd love to see it. +## Development + +This repository uses [Turborepo](https://turbo.build/) for efficient monorepo management. Turborepo provides intelligent caching and parallel execution of tasks across all packages. + +### Quick Start + +```bash +# Install dependencies +pnpm install + +# Build all packages (automatically handles dependencies) +npx turbo build + +# Build library bundles for packages that need them +npx turbo build-library + +# Run all tests +npx turbo test + +# Lint and type-check all packages +npx turbo lint type-check + +# Work on a specific package and its dependencies +npx turbo dev --filter="webamp" +``` + +### Package Dependencies + +The monorepo dependency graph is automatically managed by Turborepo: + +- `ani-cursor` and `winamp-eqf` are standalone packages built with TypeScript +- `webamp` depends on both `ani-cursor` and `winamp-eqf` for workspace linking +- All packages are built in the correct topological order +- Builds are cached and only rebuild what has changed + +### Available Tasks + +- `build` - Main build output (Vite for demos, TypeScript compilation for libraries) +- `build-library` - Library bundles for NPM publishing (only applies to `webamp`) +- `test` - Run unit tests with Jest +- `type-check` - TypeScript type checking without emitting files +- `lint` - ESLint code quality checks +- `dev` - Development server (for packages that support it) + +For more details on individual packages, see their respective README files. + [techcrunch]: https://techcrunch.com/2018/02/09/whip-the-llamas-ass-with-this-javascript-winamp-emulator/ [motherboard]: https://motherboard.vice.com/en_us/article/qvebbv/winamp-2-mp3-music-player-emulator [gizmodo]: https://gizmodo.com/winamp-2-has-been-immortalized-in-html5-for-your-pleasu-1655373653 diff --git a/package.json b/package.json index f9543050..877d6a26 100644 --- a/package.json +++ b/package.json @@ -31,18 +31,11 @@ "jest-environment-jsdom": "^29.7.0", "prettier": "^2.3.2", "stream-browserify": "^3.0.0", + "turbo": "^2.5.4", "typescript": "^5.3.3" }, "prettier": { "trailingComma": "es5" }, - "jest": { - "projects": [ - "config/jest.*.js", - "packages/ani-cursor", - "packages/winamp-eqf" - ] - }, - "dependencies": {}, "version": "0.0.0-next-87012d8d" } diff --git a/packages/webamp-docs/package.json b/packages/webamp-docs/package.json index 51876c50..a2df40db 100644 --- a/packages/webamp-docs/package.json +++ b/packages/webamp-docs/package.json @@ -22,7 +22,8 @@ "clsx": "^2.0.0", "prism-react-renderer": "^2.3.0", "react": "^19.0.0", - "react-dom": "^19.0.0" + "react-dom": "^19.0.0", + "webamp": "workspace:*" }, "devDependencies": { "@docusaurus/module-type-aliases": "3.8.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 51b58879..e479e161 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -53,6 +53,9 @@ importers: stream-browserify: specifier: ^3.0.0 version: 3.0.0 + turbo: + specifier: ^2.5.4 + version: 2.5.4 typescript: specifier: ^5.3.3 version: 5.6.3 @@ -504,6 +507,9 @@ importers: react-dom: specifier: ^19.0.0 version: 19.1.0(react@19.1.0) + webamp: + specifier: workspace:* + version: link:../webamp devDependencies: '@docusaurus/module-type-aliases': specifier: 3.8.1 @@ -12665,6 +12671,40 @@ packages: tunnel-agent@0.6.0: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + turbo-darwin-64@2.5.4: + resolution: {integrity: sha512-ah6YnH2dErojhFooxEzmvsoZQTMImaruZhFPfMKPBq8sb+hALRdvBNLqfc8NWlZq576FkfRZ/MSi4SHvVFT9PQ==} + cpu: [x64] + os: [darwin] + + turbo-darwin-arm64@2.5.4: + resolution: {integrity: sha512-2+Nx6LAyuXw2MdXb7pxqle3MYignLvS7OwtsP9SgtSBaMlnNlxl9BovzqdYAgkUW3AsYiQMJ/wBRb7d+xemM5A==} + cpu: [arm64] + os: [darwin] + + turbo-linux-64@2.5.4: + resolution: {integrity: sha512-5May2kjWbc8w4XxswGAl74GZ5eM4Gr6IiroqdLhXeXyfvWEdm2mFYCSWOzz0/z5cAgqyGidF1jt1qzUR8hTmOA==} + cpu: [x64] + os: [linux] + + turbo-linux-arm64@2.5.4: + resolution: {integrity: sha512-/2yqFaS3TbfxV3P5yG2JUI79P7OUQKOUvAnx4MV9Bdz6jqHsHwc9WZPpO4QseQm+NvmgY6ICORnoVPODxGUiJg==} + cpu: [arm64] + os: [linux] + + turbo-windows-64@2.5.4: + resolution: {integrity: sha512-EQUO4SmaCDhO6zYohxIjJpOKRN3wlfU7jMAj3CgcyTPvQR/UFLEKAYHqJOnJtymbQmiiM/ihX6c6W6Uq0yC7mA==} + cpu: [x64] + os: [win32] + + turbo-windows-arm64@2.5.4: + resolution: {integrity: sha512-oQ8RrK1VS8lrxkLriotFq+PiF7iiGgkZtfLKF4DDKsmdbPo0O9R2mQxm7jHLuXraRCuIQDWMIw6dpcr7Iykf4A==} + cpu: [arm64] + os: [win32] + + turbo@2.5.4: + resolution: {integrity: sha512-kc8ZibdRcuWUG1pbYSBFWqmIjynlD8Lp7IB6U3vIzvOv9VG+6Sp8bzyeBWE3Oi8XV5KsQrznyRTBPvrf99E4mA==} + hasBin: true + tweetnacl@0.14.5: resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} @@ -29043,6 +29083,33 @@ snapshots: dependencies: safe-buffer: 5.2.1 + turbo-darwin-64@2.5.4: + optional: true + + turbo-darwin-arm64@2.5.4: + optional: true + + turbo-linux-64@2.5.4: + optional: true + + turbo-linux-arm64@2.5.4: + optional: true + + turbo-windows-64@2.5.4: + optional: true + + turbo-windows-arm64@2.5.4: + optional: true + + turbo@2.5.4: + optionalDependencies: + turbo-darwin-64: 2.5.4 + turbo-darwin-arm64: 2.5.4 + turbo-linux-64: 2.5.4 + turbo-linux-arm64: 2.5.4 + turbo-windows-64: 2.5.4 + turbo-windows-arm64: 2.5.4 + tweetnacl@0.14.5: {} tweetnacl@1.0.3: {} diff --git a/turbo.json b/turbo.json new file mode 100644 index 00000000..c71fbfa2 --- /dev/null +++ b/turbo.json @@ -0,0 +1,55 @@ +{ + "$schema": "https://turbo.build/schema.json", + "tasks": { + "ani-cursor#build": { + "outputs": ["built/**", "dist/**"] + }, + "winamp-eqf#build": { + "outputs": ["built/**", "dist/**"] + }, + "webamp#build": { + "dependsOn": ["ani-cursor#build", "winamp-eqf#build"], + "outputs": ["dist/**"] + }, + "webamp#build-library": { + "dependsOn": [ + "ani-cursor#build", + "winamp-eqf#build", + "webamp#type-check" + ], + "outputs": ["built/**"] + }, + "webamp-docs#build": { + "dependsOn": ["webamp#build-library"], + "outputs": ["build/**", ".docusaurus/**"] + }, + "ani-cursor#type-check": {}, + "winamp-eqf#type-check": {}, + "webamp#type-check": { + "dependsOn": ["ani-cursor#build", "winamp-eqf#build"] + }, + "webamp-docs#type-check": { + "dependsOn": ["webamp#build-library"] + }, + "skin-database#type-check": {}, + "ani-cursor#test": { + "outputs": [] + }, + "winamp-eqf#test": { + "outputs": [] + }, + "webamp#test": { + "dependsOn": ["ani-cursor#build", "winamp-eqf#build"], + "outputs": [] + }, + "webamp#lint": { + "dependsOn": ["ani-cursor#build", "winamp-eqf#build"] + }, + "skin-database#lint": {}, + "webamp-modern#lint": {}, + "dev": { + "cache": false, + "persistent": true + } + } +}