Skip to content

Commit 2f26593

Browse files
balzssclaude
andcommitted
feat(many): migrate from npm to pnpm Phase 1
Implement Phase 1 of pnpm migration with workspace protocol and core tooling updates: Configuration: - Add pnpm-workspace.yaml defining workspace packages - Add .npmrc with pnpm configuration (hoisted node linker, strict peer deps) - Update lerna.json to use pnpm as npm client - Update root package.json with pnpm 10.18.3 as packageManager - Update engines requirement to pnpm >=10 - Update .gitignore for pnpm artifacts - Delete package-lock.json (replaced by pnpm-lock.yaml) Workspace Dependencies: - Convert all internal @instructure/* dependencies from exact versions to workspace:* - Update 94 package.json files across all packages Build Tooling: - Update scripts/bootstrap.js to use pnpm and run builds sequentially - Update packages/ui-scripts/lib/commands/bump.js to use pnpm install - Update packages/ui-scripts/lib/utils/npm.js to use pnpm whoami - Fix babel-plugin-transform-imports for pnpm workspace module resolution - Fix generate-all-tokens for pnpm workspace package resolution CI/CD: - Update all GitHub Actions workflows to use pnpm version 10 - Add pnpm/action-setup@v4 - Update caching to use pnpm lock files - Configure registry-url for npm publishing - Fix visual-regression.yml: use pnpm workspace protocol instead of global linking - Fix visual-regression.yml: explicitly install Cypress binary before tests - Add Cypress binary caching with lockfile hash (cypress-io/github-action#1138) TypeScript References: - Fix TypeScript project references in 10 packages (ui-drawer-layout, ui-expandable, ui-file-drop, ui-instructure, ui-link, ui-number-input, ui-popover, ui-radio-input, ui-text-area, ui-text-input) - Add missing tsconfig.build.json references to match package.json dependencies Regression Test Updates: - Update regression-test app to use @instructure/ui meta package - Convert all component imports to use single import from @instructure/ui - Update InstUISettingsProvider import path Documentation: - Add pnpm-migration-plan.md with complete migration strategy - Add pnpm-phase1-test-plan.md with testing procedures - Add pnpm-phase1-investigation.md analyzing implementation - Update building-instui.md and contributing.md with pnpm instructions Notes: - All Babel builds and token generation working successfully with pnpm - Cypress binary installation resolved by explicit `cypress install` step - Phase 2 will focus on fixing phantom dependencies and removing workarounds 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 7450ddc commit 2f26593

File tree

166 files changed

+51645
-41435
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

166 files changed

+51645
-41435
lines changed

.github/workflows/deploy.yml

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,15 @@ jobs:
1313
runs-on: ubuntu-latest
1414
steps:
1515
- uses: actions/checkout@v4
16+
- uses: pnpm/action-setup@v4
17+
with:
18+
version: 10
1619
- name: Install Node 22
1720
uses: actions/setup-node@v4
1821
with:
1922
node-version: '22'
20-
- run: npm ci && npm run bootstrap
23+
cache: 'pnpm'
24+
- run: pnpm install --frozen-lockfile && pnpm run bootstrap
2125
- name: Set build directory and deployment path based on branch
2226
id: set-build-dir
2327
run: |
@@ -37,7 +41,7 @@ jobs:
3741
;;
3842
esac
3943
- name: Build docs-app
40-
run: npm run build:docs
44+
run: pnpm run build:docs
4145
- name: Deploy to GitHub Pages
4246
uses: JamesIves/github-pages-deploy-action@v4
4347
with:
@@ -57,13 +61,17 @@ jobs:
5761
if: github.ref == 'refs/heads/master'
5862
steps:
5963
- uses: actions/checkout@v4
64+
- uses: pnpm/action-setup@v4
65+
with:
66+
version: 10
6067
- name: Install Node 22
6168
uses: actions/setup-node@v4
6269
with:
6370
node-version: '22'
64-
- run: npm ci && npm run bootstrap
71+
cache: 'pnpm'
72+
- run: pnpm install --frozen-lockfile && pnpm run bootstrap
6573
- name: Build docs-app
66-
run: npm run build:docs
74+
run: pnpm run build:docs
6775
- name: Deploy to GitHub Pages
6876
uses: JamesIves/github-pages-deploy-action@v4
6977
with:

.github/workflows/manual-release-from-pr.yml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,23 @@ jobs:
88
- uses: actions/checkout@v4
99
with:
1010
fetch-depth: 0
11+
- uses: pnpm/action-setup@v4
12+
with:
13+
version: 10
1114
- uses: actions/setup-node@v4
1215
with:
1316
node-version: '22'
14-
cache: 'npm'
17+
cache: 'pnpm'
1518
- name: Install packages
16-
run: npm ci
19+
run: pnpm install --frozen-lockfile
1720
- name: Set up project
18-
run: npm run bootstrap
21+
run: pnpm run bootstrap
1922
- name: Release to NPM
2023
env:
2124
NPM_TOKEN: ${{secrets.NPM_TOKEN}}
2225
NPM_EMAIL: ${{secrets.NPM_EMAIL}}
2326
NPM_USERNAME: ${{secrets.NPM_USERNAME}}
24-
run: npm run release -- --prRelease
27+
run: pnpm run release -- --prRelease
2528
- name: Get commit message
2629
run: | # puts the first line of the last commit message to the commmit_message env var
2730
echo "commmit_message=$(git log --format=%B -n 1 ${{ github.event.after }} | head -n 1)" >> $GITHUB_ENV

.github/workflows/manual-release-to-npm.yml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,24 @@ jobs:
88
- uses: actions/checkout@v4
99
with:
1010
fetch-depth: 0
11+
- uses: pnpm/action-setup@v4
12+
with:
13+
version: 10
1114
- name: Install Node 22
1215
uses: actions/setup-node@v4
1316
with:
1417
node-version: '22'
18+
cache: 'pnpm'
1519
- name: Install packages
16-
run: npm ci
20+
run: pnpm install --frozen-lockfile
1721
- name: Set up project
18-
run: npm run bootstrap
22+
run: pnpm run bootstrap
1923
- name: Release to NPM
2024
env:
2125
NPM_TOKEN: ${{secrets.NPM_TOKEN}}
2226
NPM_EMAIL: ${{secrets.NPM_EMAIL}}
2327
NPM_USERNAME: ${{secrets.NPM_USERNAME}}
24-
run: npm run release
28+
run: pnpm run release
2529
- name: Get commit message
2630
run: | # puts the first line of the last commit message to the commmit_message env var
2731
echo "commmit_message=$(git log --format=%B -n 1 ${{ github.event.after }} | head -n 1)" >> $GITHUB_ENV

.github/workflows/pr-validation.yml

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,46 +8,57 @@ jobs:
88
- uses: actions/checkout@v4
99
with:
1010
fetch-depth: 0
11+
- uses: pnpm/action-setup@v4
12+
with:
13+
version: 10
1114
- uses: actions/setup-node@v4
1215
with:
1316
node-version: '22'
14-
cache: 'npm'
17+
cache: 'pnpm'
1518
- name: Install dependencies
16-
run: npm ci
19+
run: pnpm install --frozen-lockfile
1720
- name: Bootstrap project
18-
run: npm run bootstrap
21+
run: pnpm run bootstrap
1922
- name: Lint commits
20-
run: npm run lint:commits
23+
run: pnpm run lint:commits
2124
- name: Lint code
22-
run: npm run lint:changes
25+
run: pnpm run lint:changes
2326
vitest-tests:
2427
name: Vitest unit tests
2528
runs-on: ubuntu-latest
2629
steps:
2730
- uses: actions/checkout@v4
31+
- uses: pnpm/action-setup@v4
32+
with:
33+
version: 10
2834
- uses: actions/setup-node@v4
2935
with:
3036
node-version: '22'
31-
cache: 'npm'
37+
cache: 'pnpm'
3238
- name: Install dependencies
33-
run: npm ci
39+
run: pnpm install --frozen-lockfile
3440
- name: Bootstrap project
35-
run: npm run bootstrap
41+
run: pnpm run bootstrap
3642
- name: Run vitest unit tests
37-
run: npm run test:vitest
43+
run: pnpm run test:vitest
3844
cypress:
3945
name: Cypress component tests
4046
runs-on: ubuntu-latest
4147
steps:
4248
- uses: actions/checkout@v4
49+
- uses: pnpm/action-setup@v4
50+
with:
51+
version: 10
4352
- uses: actions/setup-node@v4
4453
with:
4554
node-version: '22'
46-
cache: 'npm'
55+
cache: 'pnpm'
4756
- name: Install dependencies
48-
run: npm ci
57+
run: pnpm install --frozen-lockfile
58+
- name: Install Cypress binary
59+
run: npx cypress install
4960
- name: Bootstrap project
50-
run: npm run bootstrap
61+
run: pnpm run bootstrap
5162
- name: Run Cypress components tests
52-
run: npm run cy:component
63+
run: pnpm run cy:component
5364

.github/workflows/preview.yml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,19 @@ jobs:
1414
runs-on: ubuntu-latest
1515
steps:
1616
- uses: actions/checkout@v4
17+
- uses: pnpm/action-setup@v4
18+
with:
19+
version: 10
1720
- name: Install Node 22
1821
uses: actions/setup-node@v4
1922
with:
2023
node-version: '22'
21-
- name: Npm install and bootstrap
22-
run: npm ci && npm run bootstrap
24+
cache: 'pnpm'
25+
- name: Install and bootstrap
26+
run: pnpm install --frozen-lockfile && pnpm run bootstrap
2327
if: github.event.action != 'closed' # don't run install and bootstrap unnecessarily when pr is closed
2428
- name: Build docs-app
25-
run: npm run build:docs
29+
run: pnpm run build:docs
2630
if: github.event.action != 'closed'
2731
- uses: rossjrw/pr-preview-action@v1
2832
with:

.github/workflows/release.yml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,25 @@ jobs:
1111
- uses: actions/checkout@v4
1212
with:
1313
fetch-depth: 0
14+
- uses: pnpm/action-setup@v4
15+
with:
16+
version: 10
1417
- uses: actions/setup-node@v4
1518
with:
1619
node-version: '22'
17-
cache: 'npm'
20+
cache: 'pnpm'
1821
- name: Install packages.
19-
run: npm ci
22+
run: pnpm install --frozen-lockfile
2023
- name: Set up project.
21-
run: npm run bootstrap
24+
run: pnpm run bootstrap
2225
- name: Run tests.
23-
run: USE_REACT_STRICT_MODE=0 npm run test:vitest
26+
run: USE_REACT_STRICT_MODE=0 pnpm run test:vitest
2427
- name: Release to NPM
2528
env:
2629
NPM_TOKEN: ${{secrets.NPM_TOKEN}}
2730
NPM_EMAIL: ${{secrets.NPM_EMAIL}}
2831
NPM_USERNAME: ${{secrets.NPM_USERNAME}}
29-
run: npm run release
32+
run: pnpm run release
3033
tag:
3134
needs: release
3235
if: "startsWith(github.event.head_commit.message, 'chore(release)')"

.github/workflows/visual-regression.yml

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,34 @@ jobs:
1313
- uses: actions/checkout@v4
1414
with:
1515
fetch-depth: 0
16+
- uses: pnpm/action-setup@v4
17+
with:
18+
version: 10
19+
- uses: actions/setup-node@v4
20+
with:
21+
node-version: '22'
22+
cache: 'pnpm'
23+
- name: Cache Cypress binary
24+
uses: actions/cache@v4
25+
with:
26+
path: ~/.cache/Cypress
27+
key: ${{ runner.os }}-cypress-${{ hashFiles('regression-test/pnpm-lock.yaml') }}
1628
- name: Build InstUI
17-
run: npm ci && npm run bootstrap
18-
- name: Install dependencies
19-
run: npm ci
29+
run: pnpm install --frozen-lockfile && pnpm run bootstrap
30+
- name: Install regression-test dependencies
31+
run: pnpm install --frozen-lockfile
32+
working-directory: regression-test
33+
- name: Install Cypress binary
34+
run: pnpm exec cypress install
2035
working-directory: regression-test
2136
- name: Run Cypress tests
2237
uses: cypress-io/github-action@v6
2338
env:
2439
ELECTRON_EXTRA_LAUNCH_ARGS: "--remote-debugging-port=9222"
2540
with:
26-
build: npm run build
27-
start: npm start
41+
install: false
42+
build: pnpm run build
43+
start: pnpm start
2844
working-directory: regression-test
2945
- name: Upload cypress artifact for chromatic
3046
uses: actions/upload-artifact@v4
@@ -42,11 +58,17 @@ jobs:
4258
uses: actions/checkout@v4
4359
with:
4460
fetch-depth: 0
61+
- uses: pnpm/action-setup@v4
62+
with:
63+
version: 10
4564
- uses: actions/setup-node@v4
4665
with:
4766
node-version: 22
48-
- name: Install dependencies
49-
run: npm ci
67+
cache: 'pnpm'
68+
- name: Build InstUI
69+
run: pnpm install --frozen-lockfile && pnpm run bootstrap
70+
- name: Install regression-test dependencies
71+
run: pnpm install --frozen-lockfile
5072
working-directory: regression-test
5173
- name: Download Cypress test results
5274
uses: actions/download-artifact@v4

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
node_modules/
22
npm-debug.log
3+
pnpm-debug.log
34
lerna-debug.log
45
./build-storybook.log
56
coverage/
@@ -9,10 +10,10 @@ __build__
910
.idea
1011
.DS_Store
1112
.viminfo
12-
.npmrc
1313
.env
1414
.env.test
1515
.tmp/
16+
.pnpm-store/
1617

1718
tsconfig.build.tsbuildinfo
1819

@@ -31,3 +32,6 @@ tsconfig.build.tsbuildinfo
3132
.claude/commands/*
3233
!.claude/commands/commit.md
3334
!.claude/commands/pr.md
35+
36+
# Playwright MCP
37+
.playwright-mcp

.npmrc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Strict peer dependencies (recommended)
2+
auto-install-peers=false
3+
strict-peer-dependencies=true
4+
5+
# Workspace protocol
6+
link-workspace-packages=true
7+
8+
# Use hoisted node linker initially for compatibility
9+
node-linker=hoisted
10+
11+
# Can enable later for stricter isolation:
12+
# node-linker=isolated
13+
# shamefully-hoist=false

cypress/webpack.config.cjs

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,62 @@
1+
/*
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2015 - present Instructure, Inc.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
124
const path = require('path')
25+
const fs = require('fs')
26+
27+
// Generate aliases for all @instructure/* workspace packages
28+
// This is needed because Cypress tests run from the root workspace
29+
// and need to resolve workspace package imports during testing
30+
function getWorkspaceAliases() {
31+
const packagesDir = path.resolve(__dirname, '../packages')
32+
const packages = fs.readdirSync(packagesDir)
33+
const aliases = {}
34+
35+
packages.forEach((pkg) => {
36+
const pkgPath = path.join(packagesDir, pkg)
37+
if (fs.statSync(pkgPath).isDirectory()) {
38+
const pkgJsonPath = path.join(pkgPath, 'package.json')
39+
if (fs.existsSync(pkgJsonPath)) {
40+
const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'))
41+
const pkgName = pkgJson.name
42+
if (pkgName && pkgName.startsWith('@instructure/')) {
43+
// Alias package name to its source directory
44+
aliases[pkgName] = pkgPath
45+
// Also alias deep imports (e.g., '@instructure/ui-button/src/...')
46+
aliases[`${pkgName}/src`] = path.join(pkgPath, 'src')
47+
}
48+
}
49+
}
50+
})
51+
52+
return aliases
53+
}
254

355
module.exports = {
456
mode: 'development',
557
resolve: {
658
extensions: ['.ts', '.tsx', '.js'],
59+
alias: getWorkspaceAliases(),
760
fallback: {
861
fs: false,
962
module: false,
@@ -20,4 +73,4 @@ module.exports = {
2073
}
2174
]
2275
}
23-
}
76+
}

0 commit comments

Comments
 (0)