feat: Update to use pnpm (#6031)

* Initial pnpm change

* Install/update in pnpm sort of works

* Attempt to fix install

* fix pnpm

* Refactor build process to use RSPack instead of Webpack across multiple extensions and modes. Update package.json scripts for development and production builds, and adjust webpack configuration files to accommodate new plugin imports and settings.

* Update RSPack dependencies to version 2.0.0 across the project, enhancing compatibility and performance. Refactor webpack configuration in multiple extensions and modes to utilize the new library structure for UMD output. Adjust package.json scripts and settings for improved build processes.

* Implement migration guide for OHIF 3.13, detailing the transition from Webpack to Rspack v2, the shift to pnpm workspaces, and the increase in minimum Node.js version to 24. Include new build commands, plugin replacements, and updates to package configurations across the monorepo.

* Fix some dev:fast bugs

* Move netlify to top level and remove webpack builds

* Update version script to deal with lerna missing

* chore(tests): Update multiple screenshot test images for various specs

* feat(screenshot-reviewer): Add screenshot review tool and update package.json scripts

* fix(DICOMSRDisplayTool): Improve actor presence check in viewport

* chore(tests): Update multiple screenshot assets for various specs

* chore(tests): Integrate waitForPaintToSettle and waitForViewportsRendered in multiple specs for improved rendering stability

* chore(tests): Update screenshot assets for SEGHydration and SEGNoHydration specs

* test: update progressive loading screenshots

* jest 30 test fixes for compatibility with pnpm cs3d

* Use correct setDisplaySets instead of setDataId

* fix: Naming change for LegacyVolumeViewport3D

* Update to allow tolerance for contour tests

* update

* fix

* refactor: Replace instanceof checks with utility functions for viewport type validation

* fix: Update createSegmentationForViewport to handle undefined displaySetInstanceUID gracefully

* bun lock

* chore(pnpm): align workspace setup to cornerstone3D and address PR review

- .npmrc / pnpm-workspace.yaml: mirror cs3d (node-linker hoisted,
  strict-peer-dependencies=false, link/prefer workspace packages,
  minimumReleaseAge, frozenLockfile); sync axios 1.17.0 + tmp override
- root: packageManager pnpm@11.4.0, engines pnpm >=11, wire preinstall.js
- restore preinstall.js (token/private-repo + CLAUDE->AGENTS symlink)
- playwright.yml: keep base CS3D-integration workflow, switch only the
  package manager (bun/yarn -> pnpm) and node 20 -> 24
- webpack.base.js: revert prod devtool to source-map (drop hidden-source-map)
- remove @percy/cypress; .netlify + cli templates engines pnpm >=11
- Dockerfile pin pnpm@11; document tests/globalSetup.ts warmup
- drop dicom-sr -> measurement-tracking edge (breaks pnpm cyclic dep)

* chore(pnpm): regenerate lockfile and restore cs3d:* dev scripts

- Regenerate pnpm-lock.yaml against the resolved workspace (cycle removed,
  cs3d 4.22.10, workspace:* internal deps).
- Restore cs3d:checkout/check/build/watch/install/link/unlink helper scripts
  (dropped when taking the PR's root scripts), converted yarn -> pnpm since
  the local cornerstone3D checkout is now pnpm too.

* Merge base branch issues

* Link ohif app

* ci: pin pnpm to 11.4.0 in action-setup (was version: latest)

version: latest floats across runs and breaks reproducibility. Pin to the repo's packageManager version (pnpm@11.4.0) in both playwright and build-docs workflows.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix: Accidental commit of .npmrc config

* Fix build issues

* build fix

* Dependency fixes

* fix: Dependency bug in app on extensions/modes

* Fix output configuration

* Replace percy screenshots with native cypress

* Remove percy screenshot entirely

* fix: Build issues

* force click to prevent canvas cover issues

* Enable swiftshader

* Update launch of electron

* fix: Broken size calculation

* Empty change to force a re-build

* fix(cypress): generate ui-next tailwind classes; drop unsupported electron arg

Tailwind only scanned @ohif/ui-next via ../../node_modules/@ohif/ui-next, which no longer resolves under the pnpm layout, so ui-next-unique classes (e.g. toolbar split-button sizing) were never generated. Those buttons' hit-boxes collapsed, producing Cypress 'covered by element' failures on toolbar interactions. Scan ui-next by direct filesystem path like ui/extensions/modes.

Also stop pushing --enable-unsafe-swiftshader into Electron's launchOptions.args (Electron ignores it and warns); it is supplied via ELECTRON_EXTRA_LAUNCH_ARGS in CI. The arg is still pushed for non-electron chromium (local chrome).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(e2e): disable dev-server overlay during coverage runs

The rspack dev-server client overlay injects an iframe (id=rspack-dev-server-client-overlay) that intercepts pointer events, causing Playwright/Cypress clicks on toolbar buttons to time out (e.g. MicroscopyPanel). Disable the overlay when COVERAGE=true (e2e/Playwright webServer) while keeping it for normal local dev.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(microscopy): provide dicom-microscopy-viewer runtime assets

The microscopy viewer is loaded at runtime via peerImport('dicom-microscopy-viewer'), which fetches the copied asset served at /dicom-microscopy-viewer/. Two issues prevented those assets from reaching dist, so the viewer never initialized and drawing produced no measurement row:

1) dicom-microscopy-viewer was declared in no workspace package.json (only under libs/@cornerstonejs), so it was not installed at root node_modules and the pluginConfig copy source did not exist. Declare it (0.48.6, matching libs) in the microscopy extension.

2) createCopyPluginToDist appended the public/dist folder name to entries that specify an explicit directory, breaking the dicom-microscopy-viewer public entry (looked for .../dynamic-import/public). Use an explicit directory as-is; only append the folder name for package-derived entries.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Update to pnpm 11.5.2 and cs3d 5.0.2

* Lock file

* fix: Update to newer versions of actions to try to fix hang

* Remove unnecessary version

* fix: Tests that are flaky

* PR comments

* Incorrect run name

* docs: Explain pluginConfig tooling

* Updated notes on pluginConfig and PR comments

* fix: resolve plugins in rsbuild build and fix directory-based asset copy

rsbuild.config.ts: merge getPluginResolveAliases() and an @ohif/app$ alias into resolve.alias, and add resolve.modules (root, platform/app, platform/ui node_modules) so extensions resolve their shared @ohif/* imports. Brings the rsbuild (dev:fast) path to parity with webpack.pwa.js / webpack.base.js.

writePluginImportsFile.js: treat a 'directory' on an extension/mode entry as the package root and copy its public/ and dist/ subdirs instead of the whole directory; public-section entries keep copying their directory verbatim via a new literalDirectory flag.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor: share resolve alias/modules between webpack and rsbuild configs

Extract the resolve.alias (@ohif/app, @, @components, ...) and the node_modules search paths into .webpack/resolveConfig.js, the single source of truth consumed by both webpack.base.js (and every per-package webpack.prod/.dev.js that merges it) and rsbuild.config.ts. getModules(srcDir) appends the building package's own source root, preserving the previous per-package behavior. Ends the drift where the rsbuild path kept missing aliases/module paths that webpack.base.js already had.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Add a timeout on git fetch and avoid all the unnecessary mirrros

* PR comments and tests

* Remove cache to prevent corrupting the cache key/setup.

* Fix stale/corrupted pnpm installer

---------

Co-authored-by: Alireza <ar.sedghi@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
authored and GitHub committed 2026-06-12 16:04:56 -04:00
1 parent 571c2b4ff0
commit f1cc2ee13a
126 files changed
+31623 -55381

No files matched your search

+29 -26
View File
@@ -21,16 +21,22 @@ jobs:
contents: read
pull-requests: read
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
bun-version: 1.2.23
- uses: actions/setup-node@v4
persist-credentials: false
- uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 20 # Or your desired Node version
node-version: 24
cache: pnpm
- name: Install root dependencies
run: bun install --frozen-lockfile
- name: Configure git for private repos
run: git config --global url."https://${GITHUB_TOKEN}:x-oauth-basic@github.com/".insteadOf ssh://git@github.com/
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install dependencies
run: pnpm install --frozen-lockfile
# Removed Playwright tests and coverage generation steps
@@ -44,47 +50,44 @@ jobs:
# Note: This relies on the merge commit being directly pushed to main
PR_DATA=$(gh pr list --state merged --search "$MERGE_COMMIT_SHA" --json number,headRefOid --jq '.[0]')
if [ -z "$PR_DATA" ]; then
echo "Could not find merged PR for commit $MERGE_COMMIT_SHA."
# Decide how to handle - fail, or maybe generate coverage now?
# For now, let's fail.
exit 1
echo "::warning::Could not find merged PR for commit $MERGE_COMMIT_SHA. Skipping coverage embedding."
echo "coverage_found=false" >> $GITHUB_OUTPUT
exit 0
fi
PR_HEAD_SHA=$(echo "$PR_DATA" | jq -r '.headRefOid')
PR_NUMBER=$(echo "$PR_DATA" | jq -r '.number')
echo "Found PR Number: $PR_NUMBER"
echo "Found PR Head SHA: $PR_HEAD_SHA"
# Find the latest workflow run ID for the playwright workflow on the PR head commit
# Uses the workflow file name 'playwright.yml'
# Remove the --status success flag to find any run
RUN_ID=$(gh run list --workflow playwright.yml --commit "$PR_HEAD_SHA" --event pull_request --json databaseId --jq '.[0].databaseId')
# Find the latest *successful* playwright.yml run for the PR head commit so we
# never embed coverage from a failed/incomplete run.
RUN_ID=$(gh run list --workflow playwright.yml --commit "$PR_HEAD_SHA" --event pull_request --status success --json databaseId --jq '.[0].databaseId')
if [ -z "$RUN_ID" ]; then
echo "Could not find any 'playwright.yml' run for PR $PR_NUMBER (Head SHA: $PR_HEAD_SHA)."
# Decide how to handle - maybe try finding the artifact from the merge commit run if that exists?
# For now, let's fail.
exit 1
echo "::warning::Could not find a successful 'playwright.yml' run for PR $PR_NUMBER (Head SHA: $PR_HEAD_SHA). Skipping coverage embedding."
echo "coverage_found=false" >> $GITHUB_OUTPUT
exit 0
fi
echo "Found Run ID: $RUN_ID"
echo "run_id=$RUN_ID" >> $GITHUB_OUTPUT
echo "coverage_found=true" >> $GITHUB_OUTPUT
- name: Download coverage artifact from PR run
if: steps.find_pr_run.outputs.coverage_found == 'true'
env:
GH_TOKEN: ${{ github.token }}
run: |
mkdir -p ./coverage-artifact
gh run download ${{ steps.find_pr_run.outputs.run_id }} -n coverage-report-pr --dir ./coverage-artifact
# Check if download was successful (e.g., check if files exist)
if [ ! -f ./coverage-artifact/base.css ]; then
echo "Failed to download or find expected files in artifact 'coverage-report-pr' from run ${{ steps.find_pr_run.outputs.run_id }}."
# Verify the artifact contains an HTML coverage report rather than checking a single asset
if [ -z "$(ls -A ./coverage-artifact)" ] || ! ls ./coverage-artifact/*.html >/dev/null 2>&1; then
echo "Failed to download or find an HTML coverage report in artifact 'coverage-report-pr' from run ${{ steps.find_pr_run.outputs.run_id }}."
exit 1
fi
echo "Artifact downloaded successfully."
- name: Install docs dependencies
run: cd platform/docs && bun install
- name: Copy coverage to docs static directory
if: steps.find_pr_run.outputs.coverage_found == 'true'
run: |
# Copy files from the downloaded artifact directory
mkdir -p platform/docs/static/coverage
@@ -99,7 +102,7 @@ jobs:
cp ./coverage-artifact/sorter.js platform/docs/static/
- name: Build docs
run: cd platform/docs && bun run build
run: pnpm --filter ohif-docs run build
- name: Deploy to Netlify
run: |
+5 -3
View File
@@ -55,7 +55,9 @@ jobs:
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
# Add any setup steps before running the `github/codeql-action/init` action.
# This includes steps like installing compilers or runtimes (`actions/setup-node`
@@ -65,7 +67,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@dd903d2e4f5405488e5ef1422510ee31c8b32357 # v3.36.2
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
@@ -93,6 +95,6 @@ jobs:
exit 1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@dd903d2e4f5405488e5ef1422510ee31c8b32357 # v3.36.2
with:
category: "/language:${{matrix.language}}"
+25 -17
View File
@@ -29,18 +29,24 @@ jobs:
matrix:
node-version: [24]
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
bun-version: 1.2.23
- uses: pnpm/action-setup@v4
with:
version: 11.4.0
- uses: actions/setup-node@v4
persist-credentials: false
# Self-hosted runner hygiene: wipe any stale/corrupted pnpm self-install
# before action-setup reinstalls it. A prior `cache: pnpm` restore left a
# pnpm install missing dist/worker.js, breaking `pnpm install`. Plain shell
# so it runs even when pnpm itself is broken. Cheap: action-setup reinstalls.
- name: Reset stale pnpm self-install
shell: bash
run: rm -rf "$HOME/setup-pnpm"
- uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: ${{ matrix.node-version }}
- name: Install Yarn
run: npm install -g yarn@1.22.22
# No `cache: pnpm`: this is a self-hosted runner with a persistent
# pnpm store on local disk. The Actions cache doesn't preserve the
# pnpm self-install's links faithfully, dropping pnpm/dist/worker.js
# and breaking `pnpm install` with MODULE_NOT_FOUND.
# ── CS3D integration: detect label and ref type ──────────────────────
- name: Check for CS3D integration label
@@ -94,7 +100,7 @@ jobs:
# ── Common: install OHIF dependencies ───────────────────────────────
- name: Install dependencies
run: bun install --frozen-lockfile
run: pnpm install --frozen-lockfile
# ── CS3D branch path: link packages after OHIF install ──────────────
- name: Link CS3D packages
@@ -107,7 +113,7 @@ jobs:
if: steps.cs3d-check.outputs.enabled == 'true' && steps.cs3d-ref.outputs.type == 'version'
run: |
node .scripts/cs3d-set-version.mjs "${CS3D_VERSION}"
bun install --config=./bunfig.update-lockfile.toml
pnpm install --no-frozen-lockfile
env:
CS3D_VERSION: ${{ steps.cs3d-ref.outputs.version }}
@@ -117,7 +123,7 @@ jobs:
- name: Run Playwright tests
run: |
export NODE_OPTIONS="--max_old_space_size=10192"
bun run test:e2e:coverage
pnpm run test:e2e:coverage
# ── Common: collect test results and coverage ───────────────────────
- name: Create directory of test results
@@ -128,17 +134,17 @@ jobs:
cp -r ./tests/playwright-report packaged-test-results/ || true
- name: Upload directory of test results artifact
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: playwright-results
path: packaged-test-results/
retention-days: 5
- name: create the coverage report
run: |
bun nyc report --reporter=lcov --reporter=text
pnpm exec nyc report --reporter=lcov --reporter=text
- name: Upload the coverage report to GitHub Actions Artifacts
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: coverage-report-pr
path: coverage
@@ -160,7 +166,7 @@ jobs:
- name: Build OHIF viewer (CS3D preview)
if: steps.cs3d-check.outputs.enabled == 'true'
run: bun run build:ci
run: pnpm run build:ci
- name: Deploy CS3D preview to Netlify
if: steps.cs3d-check.outputs.enabled == 'true'
@@ -201,7 +207,9 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
- name: Check for CS3D branch usage
run: bash .scripts/ci/cs3d-branch-merge-guard.sh
env: