Skip to content

build: migrate from Yarn 1 to Yarn 4 - #174

Merged
behnam-oneschema merged 6 commits into
mainfrom
devin/yarn4-migration
Aug 27, 2026
Merged

build: migrate from Yarn 1 to Yarn 4#174
behnam-oneschema merged 6 commits into
mainfrom
devin/yarn4-migration

Conversation

@behnam-oneschema

@behnam-oneschema behnam-oneschema commented Aug 27, 2026

Copy link
Copy Markdown
Member

Summary

Migrates the monorepo from Yarn 1.22 to Yarn 4.18.0 (Berry) via Corepack, keeping the classic node_modules layout (nodeLinker: node-modules in .yarnrc.yml) so package builds see an identical dependency tree.

Key mechanics:

  • "packageManager": "yarn@4.18.0" pins the version; contributors just run corepack enable once (documented in CONTRIBUTING.md). No Yarn binaries are checked in — .gitignore gets the standard .yarn/* entries.
  • yarn.lock is migrated to the v8 lockfile format (large mechanical diff, marked linguist-generated).
  • Yarn 4 removed yarn workspaces run, so root scripts move to yarn workspaces foreach -A run <script> (build uses --topological-dev for dependency order). For that ordering to work, @oneschema/angular's dependency on @oneschema/importer is now declared in the workspace's devDependencies (it resolves to the local workspace, matching the published lib's existing ^0.7.0 peer range). The root clean now runs workspace cleans before rm -rf node_modules, since the old order deleted the binaries it needed.
  • Yarn 4 also removed the builtin yarn check, so bare yarn check now runs the root script — docs simplified accordingly.
  • Workflows enable Corepack before setup-node (so cache: yarn resolves through Corepack) and switch installs to yarn install --immutable. Exception: the bundle-size job's base checkout is built with corepack yarn@1.22.22 install --frozen-lockfile — while main predates this PR its lockfile is still v1 format, and an explicit Corepack pin is required because Yarn 4 otherwise refuses to run against the PR checkout's packageManager guard.
  • resolutions (human-id) and Changesets 2.31.1 are untouched; the Yarn-1 --ignore-engines friction with Changesets v3 disappears, which unblocks the publishing PR ci: publish via npm trusted publishing (OIDC), changesets cli v3 #155 cleanly.

Stacked on #172 (Node 24 + CONTRIBUTING.md); base will retarget to main when it merges.

Test plan

All under Node v24.18.0 / Yarn 4.18.0:

  • yarn install --immutable against the committed migrated lockfile — passes
  • yarn build, yarn check:packages (publint all green, attw report-only unchanged), yarn check (prettier + htmlhint + workspace checks), yarn test:ci (Angular karma 2/2 headless) — all pass
  • yarn fix produces no changes; yarn changeset --help works under Yarn 4
  • scripts/bundle-size.mjs runs against the new build output
  • actionlint v1.7.12 clean on the modified workflows
  • Base-compat verified: in a clean base checkout, corepack yarn@1.22.22 install --frozen-lockfile && corepack yarn@1.22.22 build succeeds (covers the bundle-size base install)
  • CI green; CodeRabbit full review approved with no actionable comments

Link to Devin session: https://app.devin.ai/sessions/a90df1407fe74fe990a9e3f3bfa772d3
Open in Devin Desktop: https://app.devin.ai/desktop/session/a90df1407fe74fe990a9e3f3bfa772d3?variant=devin
Requested by: @behnam-oneschema

@devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@coderabbitai

coderabbitai Bot commented Aug 27, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f3bf9e5b-a291-4227-bb73-25edfc9a0896

📥 Commits

Reviewing files that changed from the base of the PR and between 983b5b0 and 4e56108.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (7)
  • .github/workflows/ci.yml
  • .github/workflows/release.yml
  • .gitignore
  • .yarnrc.yml
  • CONTRIBUTING.md
  • package.json
  • packages/importer-angular/package.json

Limit details: You’ve used the included review currently available. Your 110 included PR review attempts over the past 7 days set your current allowance at 1 review per hour.


Walkthrough

The repository adopts Yarn 4.18.0, updates workspace commands and configuration, enables Corepack in workflows, and changes dependency installation modes for CI, release, and bundle-size jobs.

Changes

Yarn 4 migration

Layer / File(s) Summary
Workspace configuration
.yarnrc.yml, .gitignore, package.json, packages/importer-angular/package.json
The workspace declares Yarn 4.18.0, uses the node-modules linker, updates Yarn artifact ignores, changes workspace scripts, and adds @oneschema/importer as a development dependency.
Contributor command updates
CONTRIBUTING.md
Contribution instructions require Corepack and use Yarn workspace and script commands.
Automated installation paths
.github/workflows/ci.yml, .github/workflows/release.yml
CI and release workflows enable Corepack and use immutable installs. The bundle-size base environment uses Yarn 1.22.22 with a frozen lockfile.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 4e561

The dependency migration is merge-ready after normal checks and review; no actionable merge-blocking risk remains.

🚥 Pre-merge checks | ✅ 6
✅ Passed checks (6 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Security Check ✅ Passed No introduced unaddressed security concern found. The PR changes dependency tooling, workflows, and configuration only; it adds no application code or credential-handling logic. The new external depen…
Title check ✅ Passed The title uses the required Conventional Commits format with the valid type "build" and accurately describes the Yarn 1 to Yarn 4 migration.
Description check ✅ Passed The description clearly explains the Yarn migration, workflow updates, script changes, compatibility handling, and validation results. It is directly related to the changeset.
Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0 files. (7 skipped: 7 unsupported.)

Full details: Security Check

Explanation

No introduced unaddressed security concern found. The PR changes dependency tooling, workflows, and configuration only; it adds no application code or credential-handling logic. The new external dependency is the pinned htmlhint package, and the Yarn 4 lockfile uses registry resolutions with checksums. The existing GitHub Actions remain pinned to commit SHAs, PR jobs retain read-only permissions, and the release workflow remains limited to pushes on main. The added @oneschema/importer dependency resolves to the local workspace.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch devin/yarn4-migration

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

Bundle size report

Package/file Gzip size Raw size Delta vs base (gzip)
@oneschema/angular/esm2022/base-index.mjs 553 B 700 B 0 B (0.00%)
@oneschema/angular/esm2022/oneschema-angular.mjs 421 B 512 B 0 B (0.00%)
@oneschema/angular/esm2022/src/lib/oneschema.button.mjs 1,184 B 2,227 B 0 B (0.00%)
@oneschema/angular/esm2022/src/lib/oneschema.module.mjs 1,446 B 3,387 B 0 B (0.00%)
@oneschema/angular/esm2022/src/lib/oneschema.params.mjs 582 B 840 B 0 B (0.00%)
@oneschema/angular/esm2022/src/lib/oneschema.service.mjs 1,551 B 3,151 B 0 B (0.00%)
@oneschema/angular/esm2022/src/public-api.mjs 517 B 761 B 0 B (0.00%)
@oneschema/angular/fesm2022/oneschema-angular.mjs 1,402 B 4,872 B -8 B (-0.57%)
@oneschema/filefeeds-react/main.js 7,857 B 35,825 B 0 B (0.00%)
@oneschema/filefeeds-react/module.js 7,730 B 35,424 B 0 B (0.00%)
@oneschema/filefeeds/main.js 6,694 B 29,909 B 0 B (0.00%)
@oneschema/filefeeds/module.js 6,647 B 29,774 B 0 B (0.00%)
@oneschema/filefeeds/oneschema-filefeeds-0.5.3.min.js 3,278 B 9,350 B 0 B (0.00%)
@oneschema/filefeeds/oneschema-filefeeds-0.5.latest.min.js 3,282 B 9,355 B 0 B (0.00%)
@oneschema/importer/main.js 7,763 B 35,938 B 0 B (0.00%)
@oneschema/importer/module.js 7,708 B 35,712 B 0 B (0.00%)
@oneschema/importer/oneschema-importer-0.7.5.min.js 3,758 B 11,182 B 0 B (0.00%)
@oneschema/importer/oneschema-importer-0.7.latest.min.js 3,762 B 11,187 B 0 B (0.00%)
@oneschema/react/main.js 9,363 B 41,764 B 0 B (0.00%)
@oneschema/react/module.js 9,236 B 41,258 B 0 B (0.00%)
@oneschema/vue/main.js 26,040 B 110,396 B 0 B (0.00%)
@oneschema/vue/module.js 25,992 B 110,265 B 0 B (0.00%)

@devin-ai-integration

Copy link
Copy Markdown
Contributor

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 27, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@devin-ai-integration
devin-ai-integration Bot marked this pull request as ready for review August 27, 2026 22:07
@devin-ai-integration
devin-ai-integration Bot changed the base branch from devin/repo-qol to main August 27, 2026 22:46
behnam-oneschema and others added 6 commits August 27, 2026 23:51
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@behnam-oneschema
behnam-oneschema merged commit e0c8576 into main Aug 27, 2026
3 of 4 checks passed
behnam-oneschema added a commit that referenced this pull request Aug 28, 2026
## Summary

Gives the Angular workspace real linting — its `fix` was a no-op stub
and `check` only ran `tsc` — by adopting **angular-eslint 16.3.1**
(matching Angular 16), configured manually (`.eslintrc.json` + an `ng
lint` target) rather than via the schematic.

- Workspace scripts now match the repo vocabulary: `fix` = `eslint
projects --fix`, `check` = `eslint projects && tsc --noEmit`, plus an
`ng lint` CLI target. The root `check`/`fix` fan-out picks these up
automatically, so CI now gates on Angular lint.
- Fixed all preexisting findings (4 errors / 5 warnings → 0/0): removed
an unused import, and in the non-exported `oneschema.samples.ts` renamed
sample classes to `*Component` suffixes, replaced `any` with `unknown`,
and `_`-prefixed intentionally unused callback args.
- One targeted inline disable: `OneSchemaButton` in
`oneschema.button.ts` keeps its name (it's part of the published
`@oneschema/angular` API surface), with `component-class-suffix`
disabled on that line and a justification comment.
- Public API verified unchanged: `public-api.ts` exports, the
`lib-oneschema-button` selector, and the generated `.d.ts` files are
byte-identical before/after.

Stacked on #174 (Yarn 4 migration — this PR's lockfile additions are in
the v8 format).

## Test plan

Under Node 24 / Yarn 4.18.0:

- Angular workspace: `yarn fix` (no churn), `yarn check` (eslint 0
errors 0 warnings + tsc), `yarn test:ci` (karma 2/2 headless), `yarn
build` — all pass
- Root `yarn fix` + `yarn check` pass (only the preexisting non-gating
React Hooks warning remains)
- Built package public surface diffed before/after — no differences

Link to Devin session:
https://app.devin.ai/sessions/a90df1407fe74fe990a9e3f3bfa772d3
Open in Devin Desktop:
https://app.devin.ai/desktop/session/a90df1407fe74fe990a9e3f3bfa772d3?variant=devin
Requested by: @behnam-oneschema

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
behnam-oneschema added a commit that referenced this pull request Aug 28, 2026
## Summary

Redesigns the published package entrypoints so `@arethetypeswrong/cli`
passes on every package, and flips attw in `check:packages` from
report-only to **gating**.

For the 5 Rollup packages (`@oneschema/importer`, `react`, `vue`,
`filefeeds`, `filefeeds-react`):

- Each `package.json` gains an explicit `exports` map — `import` →
`./dist/module.mjs` + `./dist/index.d.mts`, `require` → `./dist/main.js`
+ `./dist/index.d.cts` — plus `"./dist/*"` (kept open deliberately: the
importer's UMD bundle is consumed via CDN deep paths) and
`"./package.json"`. `main`/`module` stay for legacy resolvers; top-level
`types` moves to the `.d.cts`.
- Rollup additionally emits `dist/module.mjs` (true-ESM twin of
`module.js`), and a new shared post-build step `scripts/dual-types.mjs`
derives `index.d.mts` (copy) and `index.d.cts` from the generated
`index.d.ts`. For packages with a default export, the `.d.cts` replaces
`export { X as default, ... }` with the interop-truthful shape:
  ```ts
declare const _default: { default: typeof X; /* named runtime exports */
};
declare namespace _default { /* type-only exports, e.g. OneSchemaParams
*/ }
  export = _default;
  ```
which matches exactly what the CJS bundle (`exports: "named"`:
`exports.default` + named + `__esModule`) provides — the bare
`require()` result is a non-callable object, and the declaration says so
— while the namespace merge preserves the full public type surface
(type-only exports like `OneSchemaParams`) for CJS/node10 consumers.
This clears attw's `MissingExportEquals`/node10/node16 findings on all
four resolution modes.
- Packaging hygiene while here: canonical `repository.url`,
`sideEffects: false`, and a `files` allowlist (Vue was shipping its
`test/` pages).
- Dependent workspaces (`react`, `vue`, `filefeeds-react`, `angular`)
get a tsconfig `paths` entry mapping `@oneschema/importer`/`filefeeds`
to the built `.d.mts`, so local `tsc` doesn't misread the new `.d.cts`
under their legacy `moduleResolution: node`. The Angular spec tsconfig
clears `paths` so Karma specs resolve the installed package (runtime +
its complete `.d.cts` types). Vue's internal import gains a `.js`
extension so its emitted declarations resolve under node16 ESM.

`@oneschema/angular` is left as-is: it's the standard ng-packagr 16
ESM-only shape, and I verified a `"type": "module"` post-process just
trades `FalseCJS` for `InternalResolutionError` (extensionless imports
in generated d.ts). Its attw run uses `--profile esm-only --ignore-rules
cjs-resolves-to-esm false-cjs` with a comment noting a real fix needs
the Angular 17+ toolchain. Verified the built Angular declarations keep
bare `@oneschema/importer` specifiers (no deep paths leak).

Ships a **patch** changeset for the 5 packages — deliberately not minor:
`@oneschema/angular` peer-depends on `importer@^0.7.0` and the packages
are `linked`, so a minor (0.8.0) would knock the peer range out-of-range
and cascade the whole linked group to a 1.0.0 major.

Stacked on #175 (angular-eslint) → #174 (Yarn 4).

## Test plan

- `yarn build` + `yarn check:packages`: publint and attw green on all 6
packages (previously 5/6 had attw findings)
- attw per-package: node10 / node16-CJS / node16-ESM / bundler all 🟢 for
the 5 Rollup packages
- Runtime sanity: `require("./dist/main.js").default` is a function;
`import x from "./dist/module.mjs"` is a function
- CJS/node10-mode consumer probe: `.default(...)` call +
`OneSchemaParams` type import from `@oneschema/importer` both typecheck;
negative probe confirms calling the bare `require()` result fails with
TS2349 (matching runtime)
- `yarn workspace @oneschema/angular check`; `@oneschema/angular-example
test:ci` Chrome Headless 2/2 specs
- `yarn fix`, workspace `check`s, root `yarn check` all pass (only
preexisting filefeeds-react hooks warning)
- `yarn changeset status`: all 6 publishable packages at patch, no major
cascade

Link to Devin session:
https://app.devin.ai/sessions/a90df1407fe74fe990a9e3f3bfa772d3
Open in Devin Desktop:
https://app.devin.ai/desktop/session/a90df1407fe74fe990a9e3f3bfa772d3?variant=devin
Requested by: @behnam-oneschema

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant