Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .github/actions/build-ts-loader/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Build ts-loader
description: >
Install and build ts-loader (expects actions/checkout to have already run).
On Windows runners this first copies the checkout to C:\source\ts-loader
and installs/builds there, giving a consistent path that the comparison
tests' output normalisation expects - later Windows steps should use
working-directory: C:\source\ts-loader.
runs:
using: composite
steps:
- name: copy files
if: runner.os == 'Windows'
shell: pwsh
run: |
New-Item C:\source\ts-loader -ItemType Directory
Copy-Item .\* C:\source\ts-loader -Recurse -Force

- name: install
shell: bash
working-directory: ${{ runner.os == 'Windows' && 'C:\source\ts-loader' || '.' }}
run: yarn install

- name: build
shell: bash
working-directory: ${{ runner.os == 'Windows' && 'C:\source\ts-loader' || '.' }}
run: yarn build
2 changes: 1 addition & 1 deletion .github/scripts/post-benchmark-comment.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const fs = require('fs');

/**
* Creates or updates the benchmark result comment identified by `marker`.
* Shared by the "comment on PR" steps in benchmark.yml (Ubuntu + Windows jobs).
* Used by the "comment on PR" step of each OS in benchmark.yml's matrix.
*
* @param {{
* github: { rest: { issues: {
Expand Down
154 changes: 43 additions & 111 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,34 @@ permissions:
pull-requests: write

jobs:
benchmark_ubuntu:
name: Benchmark Ubuntu
runs-on: ubuntu-latest
benchmark:
name: benchmark ${{ matrix.name }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
id: ubuntu
name: ubuntu
title: Ubuntu
- os: macos-latest
id: macos
name: macOS
title: macOS
- os: windows-latest
id: windows
name: windows
title: Windows
runs-on: ${{ matrix.os }}
timeout-minutes: 20
defaults:
run:
shell: bash
env:
# Where the build-ts-loader action builds the PR branch - on Windows it
# copies the checkout to C:\source\ts-loader first. The base branch is
# checked out alongside it at "$ROOT-main".
ROOT: ${{ matrix.os == 'windows-latest' && 'C:/source/ts-loader' || github.workspace }}
steps:
- uses: actions/checkout@v7
with:
Expand All @@ -30,42 +54,41 @@ jobs:
node-version: 24
cache: yarn

- name: install & build (PR branch)
run: |
yarn install
yarn build
- uses: ./.github/actions/build-ts-loader

# Checked out into a sibling worktree rather than a second checkout step
# so both builds can run from disk at the same time.
- name: checkout base branch into a worktree
working-directory: ${{ env.ROOT }}
env:
BASE_SHA: ${{ github.event.pull_request.base.sha || 'origin/main' }}
run: git worktree add ../ts-loader-main "$BASE_SHA"
run: git worktree add "$ROOT-main" "$BASE_SHA"

- name: install & build (base branch)
working-directory: ../ts-loader-main
working-directory: ${{ env.ROOT }}-main
run: |
yarn install
yarn build

# --root-a is the PR branch checked out at $GITHUB_WORKSPACE above;
# --root-a is the PR branch built by the build-ts-loader action;
# --root-b is the base branch worktree built in the previous step.
- name: run benchmark
working-directory: ${{ env.ROOT }}
run: |
yarn benchmark -- \
--root-a "$GITHUB_WORKSPACE" --label-a "PR branch" \
--root-b "$GITHUB_WORKSPACE/../ts-loader-main" --label-b "base branch"
--root-a "$ROOT" --label-a "PR branch" \
--root-b "$ROOT-main" --label-b "base branch"

- name: write job summary
if: always()
run: cat .benchmark/benchmark-results.md >> "$GITHUB_STEP_SUMMARY" 2>/dev/null || true
run: cat "$ROOT/.benchmark/benchmark-results.md" >> "$GITHUB_STEP_SUMMARY" 2>/dev/null || true

- name: upload results
if: always()
uses: actions/upload-artifact@v7
with:
name: benchmark-results-ubuntu
path: .benchmark/benchmark-results.*
name: benchmark-results-${{ matrix.id }}
path: ${{ env.ROOT }}/.benchmark/benchmark-results.*
if-no-files-found: ignore

# Only runs with a writable token - GitHub automatically issues a
Expand All @@ -74,108 +97,17 @@ jobs:
- name: comment on PR
if: always() && github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const path = require('path');
const postComment = require(path.join(process.env.GITHUB_WORKSPACE, '.github/scripts/post-benchmark-comment.js'));
await postComment({
github,
context,
resultsPath: '.benchmark/benchmark-results.md',
marker: '<!-- ts-loader-benchmark:ubuntu -->',
title: 'Benchmark (Ubuntu)',
});

benchmark_windows:
name: Benchmark Windows
runs-on: windows-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0

- uses: actions/setup-node@v7
with:
node-version: 24
cache: yarn

# Windows Defender's real-time scanning adds unpredictable latency to
# file I/O, and this benchmark does a lot of it (a 300-file fixture,
# webpack output per build, a touched file on every incremental
# iteration) - excluding the working directories keeps that noise out
# of the measurements.
- name: exclude working directories from Windows Defender
shell: pwsh
run: |
Add-MpPreference -ExclusionPath "C:\source"
Add-MpPreference -ExclusionPath "$env:GITHUB_WORKSPACE"

- name: copy files
shell: pwsh
run: |
New-Item C:\source\ts-loader -ItemType Directory
Copy-Item .\* C:\source\ts-loader -Recurse -Force

- name: install & build (PR branch)
run: |
yarn install
yarn build
working-directory: C:\source\ts-loader

# Checked out into a sibling worktree rather than a second checkout step
# so both builds can run from disk at the same time.
- name: checkout base branch into a worktree
shell: pwsh
env:
BASE_SHA: ${{ github.event.pull_request.base.sha || 'origin/main' }}
run: git worktree add C:\source\ts-loader-main $env:BASE_SHA
working-directory: C:\source\ts-loader

- name: install & build (base branch)
run: |
yarn install
yarn build
working-directory: C:\source\ts-loader-main

# --root-a is the PR branch copied to C:\source\ts-loader above;
# --root-b is the base branch worktree built in the previous step.
- name: run benchmark
shell: pwsh
run: |
yarn benchmark -- `
--root-a C:\source\ts-loader --label-a "PR branch" `
--root-b C:\source\ts-loader-main --label-b "base branch"
working-directory: C:\source\ts-loader

- name: write job summary
if: always()
shell: pwsh
run: |
if (Test-Path .benchmark\benchmark-results.md) {
Get-Content .benchmark\benchmark-results.md | Out-File -Append -Encoding utf8 $env:GITHUB_STEP_SUMMARY
}
working-directory: C:\source\ts-loader

- name: upload results
if: always()
uses: actions/upload-artifact@v7
with:
name: benchmark-results-windows
path: C:\source\ts-loader\.benchmark\benchmark-results.*
if-no-files-found: ignore

- name: comment on PR
if: always() && github.event_name == 'pull_request'
uses: actions/github-script@v7
MARKER: <!-- ts-loader-benchmark:${{ matrix.id }} -->
TITLE: Benchmark (${{ matrix.title }})
with:
script: |
const path = require('path');
const postComment = require(path.join(process.env.GITHUB_WORKSPACE, '.github/scripts/post-benchmark-comment.js'));
await postComment({
github,
context,
resultsPath: 'C:\\source\\ts-loader\\.benchmark\\benchmark-results.md',
marker: '<!-- ts-loader-benchmark:windows -->',
title: 'Benchmark (Windows)',
resultsPath: path.join(process.env.ROOT, '.benchmark/benchmark-results.md'),
marker: process.env.MARKER,
title: process.env.TITLE,
});
27 changes: 27 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: ci

on:
push:
branches: [main]
pull_request:
workflow_dispatch:

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
comparison-tests:
name: comparison tests
uses: ./.github/workflows/comparison-tests.yml

execution-tests:
name: execution tests
uses: ./.github/workflows/execution-tests.yml

lint:
name: lint
uses: ./.github/workflows/lint.yml
57 changes: 57 additions & 0 deletions .github/workflows/comparison-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: comparison tests

on:
workflow_call:

jobs:
comparison_test_ubuntu:
name: ubuntu
runs-on: ubuntu-latest
timeout-minutes: 25
steps:
- uses: actions/checkout@v7

- uses: actions/setup-node@v7
with:
node-version: 24
cache: yarn

- uses: ./.github/actions/build-ts-loader

- name: test
run: yarn comparison-tests

comparison_test_macos:
name: macOS
runs-on: macos-latest
timeout-minutes: 25
steps:
- uses: actions/checkout@v7

- uses: actions/setup-node@v7
with:
node-version: 24
cache: yarn

- uses: ./.github/actions/build-ts-loader

- name: test
run: yarn comparison-tests

comparison_test_windows:
name: windows
runs-on: windows-latest
timeout-minutes: 25
steps:
- uses: actions/checkout@v7

- uses: actions/setup-node@v7
with:
node-version: 24
cache: yarn

- uses: ./.github/actions/build-ts-loader

- name: test
run: yarn comparison-tests
working-directory: C:\source\ts-loader
Loading
Loading