diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 2db9dc995b..d49a1f0f33 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -12,3 +12,14 @@ updates: dependencies: patterns: - "*" + - package-ecosystem: github-actions + directory: "/" + schedule: + interval: weekly + time: "04:00" + timezone: Europe/Berlin + open-pull-requests-limit: 3 + groups: + dependencies: + patterns: + - "*" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..0dd60c5852 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,87 @@ +name: CI + +on: + push: + branches: + - main + - next + pull_request: + branches: + - main + - next + +concurrency: + group: "${{ github.workflow }} ✨ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}" + cancel-in-progress: true + +permissions: + contents: read + +jobs: + lint: + name: Lint & Check Types + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + + - name: Setup Node.js + uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 + with: + node-version: "lts/*" + cache: "npm" + + - name: Install dependencies + run: npm ci + + - name: Lint + run: npm run lint + + - name: Build types + run: npm run build:types + + - name: Check types + run: | + if [ -n "$(git status types --porcelain)" ]; then + echo "Missing types. Update types by running 'npm run build:types'"; + exit 1; + fi + test: + name: Test - ${{ matrix.os }} (Node.js ${{ matrix.node-version }}) + + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + node-version: [18.x, 20.x, 22.x, 24.x] + + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout code + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + + - name: Setup Node.js ${{ matrix.node-version }} + uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 + with: + node-version: ${{ matrix.node-version }} + cache: "npm" + + - name: Install dependencies + run: npm ci + + - name: Link webpack-dev-server + run: | + cp -R client tmp-client + npm link --ignore-scripts + npm link webpack-dev-server --ignore-scripts + rm -r client + cp -R tmp-client client + + - name: Run tests + run: npm run test:coverage -- --ci + + - name: Upload coverage to Codecov + if: always() + uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2 diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml new file mode 100644 index 0000000000..6f64e9a435 --- /dev/null +++ b/.github/workflows/commitlint.yml @@ -0,0 +1,34 @@ +name: Validate PR + +on: + pull_request: + types: + - opened + - reopened + - edited + +concurrency: + group: "${{ github.workflow }} ✨ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}" + cancel-in-progress: true + +permissions: + contents: read + +jobs: + commitlint: + name: Lint Commit Messages + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + with: + fetch-depth: 0 + + - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 + with: + node-version: "lts/*" + cache: "npm" + + - run: npm ci + + - name: Validate PR commits with commitlint + run: npx commitlint --from ${{ github.event.pull_request.head.sha }}~${{ github.event.pull_request.commits }} --to ${{ github.event.pull_request.head.sha }} --verbose diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 8caf799d12..a30d16caba 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -1,5 +1,14 @@ -name: "Dependency Review" -on: [pull_request] +# Dependency Review Action +# +# This Action will scan dependency manifest files that change as part of a Pull Request, +# surfacing known-vulnerable versions of the packages declared or updated in the PR. +# Once installed, if the workflow run is marked as required, +# PRs introducing known-vulnerable packages will be blocked from merging. +# +# Source repository: https://github.com/actions/dependency-review-action +name: Review Dependencies + +on: pull_request permissions: contents: read @@ -8,7 +17,8 @@ jobs: dependency-review: runs-on: ubuntu-latest steps: - - name: "Checkout Repository" - uses: actions/checkout@v4 - - name: "Dependency Review" - uses: actions/dependency-review-action@v4 + - name: Git Checkout + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + + - name: Review Dependencies + uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4.8.2 diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml deleted file mode 100644 index 74945cdeb6..0000000000 --- a/.github/workflows/nodejs.yml +++ /dev/null @@ -1,125 +0,0 @@ -name: webpack-dev-server - -on: - push: - branches: - - main - - next - - v4 - pull_request: - branches: - - main - - next - - v4 - -permissions: - contents: read - -jobs: - lint: - name: Lint - ${{ matrix.os }} - Node v${{ matrix.node-version }} - - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - strategy: - matrix: - os: [ubuntu-latest] - node-version: [lts/*] - - runs-on: ${{ matrix.os }} - - concurrency: - group: lint-${{ matrix.os }}-v${{ matrix.node-version }}-${{ github.ref }} - cancel-in-progress: true - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - cache: "npm" - - - name: Install dependencies - run: npm ci - - - name: Lint - run: npm run lint - - - name: Build types - run: npm run build:types - - - name: Check types - run: if [ -n "$(git status types --porcelain)" ]; then echo "Missing types. Update types by running 'npm run build:types'"; exit 1; else echo "All types are valid"; fi - - - name: Security audit - run: npm audit --production - - - name: Validate PR commits with commitlint - if: github.event_name == 'pull_request' - run: npx commitlint --from ${{ github.event.pull_request.head.sha }}~${{ github.event.pull_request.commits }} --to ${{ github.event.pull_request.head.sha }} --verbose - - test: - name: Test - ${{ matrix.os }} - Node v${{ matrix.node-version }}, Webpack ${{ matrix.webpack-version }} (${{ matrix.shard }}) - - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macos-latest] - node-version: [18.x, 20.x, 22.x, 24.x] - shard: ["1/4", "2/4", "3/4", "4/4"] - webpack-version: [latest] - - runs-on: ${{ matrix.os }} - - concurrency: - group: test-${{ matrix.os }}-v${{ matrix.node-version }}-${{ matrix.webpack-version }}-${{ matrix.shard }}-${{ github.ref }} - cancel-in-progress: true - - steps: - - uses: actions/checkout@v4 - - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - cache: "npm" - - - name: Install dependencies - run: npm ci - - - name: Install dependencies for Node.js@18 - run: | - npm i p-retry@^4.5.0 open@^8.0.9 - node ./scripts/prepare-test-for-old-node.js - if: matrix.node-version == '18.x' - - - name: Setup firefox - if: matrix.os != 'windows-latest' - uses: browser-actions/setup-firefox@latest - with: - firefox-version: latest - - - name: Link webpack-dev-server - run: | - cp -R client tmp-client - npm link --ignore-scripts || true - npm link webpack-dev-server --ignore-scripts || true - rm -r client - cp -R tmp-client client - - - name: Run tests for webpack version ${{ matrix.webpack-version }} - run: node_modules/.bin/jest --coverage --ci --shard=${{ matrix.shard }} - if: matrix.node-version == '18.x' - - - name: Run tests for webpack version ${{ matrix.webpack-version }} - run: npm run test:coverage -- --ci --shard=${{ matrix.shard }} - if: matrix.node-version != '18.x' - - - name: Submit coverage data to codecov - uses: codecov/codecov-action@v5 - with: - token: ${{ secrets.CODECOV_TOKEN }} diff --git a/scripts/prepare-test-for-old-node.js b/scripts/prepare-test-for-old-node.js deleted file mode 100644 index a5ef6dbfa1..0000000000 --- a/scripts/prepare-test-for-old-node.js +++ /dev/null @@ -1,32 +0,0 @@ -"use strict"; - -const fs = require("node:fs"); -const path = require("node:path"); - -/** - * @returns {Promise} - */ -async function setup() { - const serverCodePath = path.resolve(__dirname, "../lib/Server.js"); - let serverCode = await fs.promises.readFile(serverCodePath, "utf8"); - - serverCode = serverCode.replaceAll( - /\(await import\((".+")\)\)\.default/g, - "require($1)", - ); - - await fs.promises.writeFile(serverCodePath, serverCode); -} - -Promise.resolve() - .then(() => setup()) - // eslint-disable-next-line unicorn/prefer-top-level-await - .then( - () => { - // eslint-disable-next-line no-console - console.log("The setup was successful"); - }, - (error) => { - throw error; - }, - ); diff --git a/test/server/open-option.test.js b/test/server/open-option.test.js index fea4bf65a6..efc085b0b1 100644 --- a/test/server/open-option.test.js +++ b/test/server/open-option.test.js @@ -9,32 +9,17 @@ const internalIPv4 = Server.internalIPSync("v4"); let open; -const needRequireMock = - process.version.startsWith("v18") || process.version.startsWith("v19"); - -if (needRequireMock) { - open = require("open"); - - jest.mock("open"); - - open.mockImplementation(() => ({ - catch: jest.fn(), - })); -} - describe('"open" option', () => { let compiler; beforeEach(async () => { compiler = webpack(config); - if (!needRequireMock) { - jest.unstable_mockModule("open", () => ({ - default: jest.fn(() => Promise.resolve()), - })); + jest.unstable_mockModule("open", () => ({ + default: jest.fn(() => Promise.resolve()), + })); - open = (await import("open")).default; - } + open = (await import("open")).default; }); afterEach(async () => {