diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..0ca518a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,262 @@ +name: CI +on: + push: + paths: + - ".github/workflows/ci.yml" + - ".github/workflows/release.yml" + - "hatch_build.py" + - "package.json" + - "pyproject.toml" + - "rollup.config.js" + - "run.ts" + - "src/**" + - "yt_dlp_ejs/**" + pull_request: + paths: + - ".github/workflows/ci.yml" + - ".github/workflows/release.yml" + - "hatch_build.py" + - "package.json" + - "pyproject.toml" + - "rollup.config.js" + - "run.ts" + - "src/**" + - "yt_dlp_ejs/**" + +permissions: + contents: read + +concurrency: + group: ci-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + prepare: + name: Prepare + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - name: Install Deno v2.x (latest) + uses: denoland/setup-deno@v2 + with: + deno-version: v2.x + - name: Install Deno requirements + run: | + deno install + - name: Build control bundle + run: | + deno task bundle + - name: Generate bundle hashes + run: | + pushd dist + sha256sum -- yt.solver.*.js | tee SHA2-256SUMS + popd + - name: Upload bundle hashes + uses: actions/upload-artifact@v4 + with: + name: bundle-hashes + path: | + dist/SHA2-256SUMS + compression-level: 0 + - name: Download player JS files + run: | + deno run \ + --no-prompt \ + --allow-read=src/yt/solver/test/players/ \ + --allow-write=src/yt/solver/test/players/ \ + --allow-net=www.youtube.com \ + src/yt/solver/test/download.ts + - name: Upload player JS artifact + uses: actions/upload-artifact@v4 + with: + name: player-js + path: | + src/yt/solver/test/players/* + compression-level: 0 + + deno_build: + name: Test Deno build + needs: [prepare] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - name: Install Deno + uses: denoland/setup-deno@v2 + with: + deno-version: "2.0.0" # minimum supported version + - uses: actions/setup-python@v6 + with: + python-version: "3.10" # minimum supported version + - name: Install Python requirements + run: | + python -m pip install -U build + - name: Test Deno build + run: | + python -m build + - name: Install Deno requirements + run: | + deno install + - name: Bundle with Deno + run: | + deno task bundle + - name: Download bundle hashes + uses: actions/download-artifact@v5 + with: + path: dist + name: bundle-hashes + - name: Verify bundle hashes + run: | + cd dist + sha256sum -c SHA2-256SUMS + + deno_tests: + name: Run Deno tests + needs: [prepare] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - name: Install Deno + uses: denoland/setup-deno@v2 + with: + deno-version: "2.0.0" # minimum supported version + - name: Install Deno requirements + run: | + deno install + - name: Download player JS artifact + uses: actions/download-artifact@v5 + with: + path: src/yt/solver/test/players + name: player-js + - name: Run Deno tests + run: | + deno test \ + --no-prompt \ + --allow-read=src/yt/solver/test/players/ + + bun_build: + name: Test Bun build + needs: [prepare] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - name: Install Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: "1.0.31" # minimum supported version + - uses: actions/setup-python@v6 + with: + python-version: "3.10" # minimum supported version + - name: Install Python requirements + run: | + python -m pip install -U build + - name: Test Bun build + run: | + python -m build + - name: Install Bun requirements + run: | + bun install + - name: Bundle with Bun + run: | + bun run bundle + - name: Download bundle hashes + uses: actions/download-artifact@v5 + with: + path: dist + name: bundle-hashes + - name: Verify bundle hashes + run: | + cd dist + sha256sum -c SHA2-256SUMS + + bun_tests: + name: Run Bun tests + needs: [prepare] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - name: Install Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: "1.2.11" # XXX: We support 1.0.31, but test suite requires 1.2.11+ + - name: Install Bun requirements + run: | + bun install + - name: Download player JS artifact + uses: actions/download-artifact@v5 + with: + path: src/yt/solver/test/players + name: player-js + - name: Run Bun tests + run: | + bun test + + node_build: + name: Test Node build + needs: [prepare] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - name: Install Node + uses: actions/setup-node@v6 + with: + node-version: "20.0" # minimum supported version + - uses: actions/setup-python@v6 + with: + python-version: "3.10" # minimum supported version + - name: Install Python requirements + run: | + python -m pip install -U build + - name: Test Node build + run: | + python -m build + - name: Install Node requirements + run: | + npm install + - name: Bundle with Node + run: | + npm run bundle + - name: Download bundle hashes + uses: actions/download-artifact@v5 + with: + path: dist + name: bundle-hashes + - name: Verify bundle hashes + run: | + cd dist + sha256sum -c SHA2-256SUMS + + node_tests: + name: Run Node tests + needs: [prepare] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - name: Install Node + uses: actions/setup-node@v6 + with: + node-version: "22.18" # XXX: We support 20.0, but test suite requires 22.18+ + - name: Install Node requirements + run: | + npm install + - name: Download player JS artifact + uses: actions/download-artifact@v5 + with: + path: src/yt/solver/test/players + name: player-js + - name: Run Node tests + run: | + node --test + + all_passed: + needs: [deno_build, deno_tests, bun_build, bun_tests, node_build, node_tests] + runs-on: ubuntu-latest + steps: + - name: All checks passed + run: | + echo "All checks passed!" diff --git a/src/yt/solver/test/io.ts b/src/yt/solver/test/io.ts index 1fd7c81..a7ae0aa 100644 --- a/src/yt/solver/test/io.ts +++ b/src/yt/solver/test/io.ts @@ -23,7 +23,8 @@ export async function getIO(): Promise { } async function _getIO(): Promise { - if (globalThis.process?.release?.name === "node") { + // Old Deno requires casting to any as globalThis lacks an index signature + if ((globalThis as any).process?.release?.name === "node") { // Assume node compatibility const { access, readFile } = await import("node:fs/promises"); const { deepStrictEqual } = await import("node:assert"); diff --git a/src/yt/solver/test/tests.ts b/src/yt/solver/test/tests.ts index 22a7211..7071c98 100644 --- a/src/yt/solver/test/tests.ts +++ b/src/yt/solver/test/tests.ts @@ -236,7 +236,9 @@ export const tests: { ], }, { + // TODO: es6/tv_es6 variants currently fail player: "2b83d2e0", + variants: ["main", "tcc", "tce", "es5", "tv", "phone", "tablet"], n: [ // Synthetic test { input: "0eRGgQWJGfT5rFHFj", expected: "euHbygrCMLksxd" },