Skip to content

Commit 099b3b1

Browse files
authored
Merge branch 'main' into deps/upstream-update
2 parents cf2dad1 + 3597f54 commit 099b3b1

3 files changed

Lines changed: 127 additions & 4 deletions

File tree

.github/workflows/upgrade-deps.yml

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,9 @@ jobs:
8282
- Upgrade script: `./.github/scripts/upgrade-deps.ts`
8383
- Sync-remote tool: `pnpm tool sync-remote` (source in
8484
`packages/tools/src/sync-remote-deps.ts`) — clones rolldown/vite into the
85-
working tree and merges their pnpm-workspace catalogs into the root
86-
`pnpm-workspace.yaml`.
85+
working tree, merges their pnpm-workspace catalogs into the root
86+
`pnpm-workspace.yaml`, and syncs the root `Cargo.toml` oxc crate
87+
versions to match `rolldown/Cargo.toml`.
8788
- Build-upstream action: `./.github/actions/build-upstream/action.yml`
8889
- Package manager: `pnpm`. Do NOT downgrade any dep — we want the latest.
8990
@@ -105,7 +106,15 @@ jobs:
105106
then re-run `pnpm tool sync-remote` until it exits 0. Finish with
106107
`pnpm install --no-frozen-lockfile`.
107108
2. Re-run the steps in `./.github/actions/build-upstream/action.yml`; fix any
108-
non-zero exits.
109+
non-zero exits. If the Rust build fails inside a vendored `rolldown`
110+
crate with an oxc API mismatch (e.g. `oxc_ast::template_element` taking
111+
a different number of arguments, or any `oxc_*` type/signature error),
112+
the root `Cargo.toml` oxc pins are out of sync with the bumped rolldown.
113+
`pnpm tool sync-remote` should already reconcile them; if any `oxc_*`
114+
entry in the root `Cargo.toml [workspace.dependencies]` still differs
115+
from `rolldown/Cargo.toml`, bump it to match (the oxc same-version
116+
family follows rolldown's umbrella `oxc` version), run `cargo update`,
117+
and rebuild.
109118
3. If the rolldown hash changed, follow `.claude/agents/cargo-workspace-merger.md`
110119
to resync the workspace.
111120
4. Compare tsdown CLI options with `vp pack` and sync new/removed options per
@@ -182,6 +191,12 @@ jobs:
182191
pnpm dedupe
183192
184193
- name: Format code
194+
# `pnpm fmt` runs `vp fmt`, which loads the freshly built NAPI binding. When
195+
# `build-upstream` fails (e.g. an upstream rolldown/oxc desync the in-workflow
196+
# fixup could not resolve) the binding is never produced and `vp fmt` aborts.
197+
# Keep going so the PR is still created with the broken state surfaced for review,
198+
# matching the `continue-on-error` on the build steps above.
199+
continue-on-error: true
185200
run: pnpm fmt
186201

187202
- name: Enhance PR description with Claude

packages/tools/src/__tests__/sync-remote-deps.spec.ts

Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { describe, expect, test } from '@voidzero-dev/vite-plus-test';
22
import * as semver from 'semver';
33

4-
import { mergePnpmWorkspaces } from '../sync-remote-deps.ts';
4+
import { mergePnpmWorkspaces, syncCargoOxcVersions } from '../sync-remote-deps.ts';
55

66
describe('mergePnpmWorkspaces() minimumReleaseAgeExclude', () => {
77
test('drops versioned upstream entries already covered by a glob or bare pattern', () => {
@@ -80,3 +80,107 @@ describe('mergePnpmWorkspaces() minimumReleaseAgeExclude', () => {
8080
expect(result.minimumReleaseAgeExclude).toEqual(['@oxc-parser/*', 'oxc-parser']);
8181
});
8282
});
83+
84+
// Reproduces the upstream-upgrade build break: when the bumped rolldown hash
85+
// pins a newer oxc release (e.g. 0.135.0 / oxc_index 5), the vendored rolldown
86+
// crates fail to compile against vp's stale `Cargo.toml` oxc pin (0.134.0). The
87+
// root `Cargo.toml` oxc versions must follow rolldown's `Cargo.toml`.
88+
describe('syncCargoOxcVersions()', () => {
89+
const mainCargo = `[workspace]
90+
members = ["crates/*"]
91+
92+
[workspace.dependencies]
93+
serde = "1"
94+
95+
# oxc crates with the same version
96+
oxc = { version = "0.134.0", features = [
97+
"ast_visit",
98+
"transformer",
99+
] }
100+
oxc_allocator = { version = "0.134.0", features = ["pool"] }
101+
oxc_ast = "0.134.0"
102+
oxc_parser = "0.134.0"
103+
oxc_span = "0.134.0"
104+
oxc_traverse = "0.134.0"
105+
106+
# oxc crates in their own repos
107+
oxc_index = { version = "4", features = ["rayon", "serde"] }
108+
oxc_resolver = { version = "11.21.0", features = ["yarn_pnp"] }
109+
oxc_sourcemap = "7"
110+
111+
[profile.release]
112+
lto = true
113+
`;
114+
115+
const rolldownCargo = `[workspace]
116+
members = ["crates/*"]
117+
118+
[workspace.dependencies]
119+
# oxc crates with the same version
120+
oxc = { version = "0.135.0", features = [
121+
"ast_visit",
122+
"transformer",
123+
] }
124+
oxc_allocator = { version = "0.135.0", features = ["pool"] }
125+
oxc_traverse = { version = "0.135.0" }
126+
127+
# oxc crates in their own repos
128+
oxc_index = { version = "5", features = ["rayon", "serde"] }
129+
oxc_resolver = { version = "11.21.0", features = ["yarn_pnp"] }
130+
oxc_sourcemap = { version = "7" }
131+
`;
132+
133+
test('bumps the oxc same-version family and oxc_index to match rolldown', () => {
134+
const { content, changes } = syncCargoOxcVersions(mainCargo, rolldownCargo);
135+
136+
// Same-version family follows rolldown's umbrella `oxc` version, including
137+
// crates rolldown does not declare explicitly (oxc_ast/oxc_parser/oxc_span).
138+
expect(content).toContain('oxc = { version = "0.135.0"');
139+
expect(content).toContain('oxc_allocator = { version = "0.135.0"');
140+
expect(content).toContain('oxc_ast = "0.135.0"');
141+
expect(content).toContain('oxc_parser = "0.135.0"');
142+
expect(content).toContain('oxc_span = "0.135.0"');
143+
expect(content).toContain('oxc_traverse = "0.135.0"');
144+
// Independently-versioned crate follows rolldown's own pin.
145+
expect(content).toContain('oxc_index = { version = "5"');
146+
// Unchanged crates stay put.
147+
expect(content).toContain('oxc_resolver = { version = "11.21.0"');
148+
expect(content).toContain('oxc_sourcemap = "7"');
149+
// Features and unrelated entries are preserved.
150+
expect(content).toContain('"ast_visit",');
151+
expect(content).toContain('serde = "1"');
152+
153+
const changed = Object.fromEntries(changes.map((c) => [c.key, c.to]));
154+
expect(changed).toMatchObject({
155+
oxc: '0.135.0',
156+
oxc_allocator: '0.135.0',
157+
oxc_ast: '0.135.0',
158+
oxc_parser: '0.135.0',
159+
oxc_span: '0.135.0',
160+
oxc_traverse: '0.135.0',
161+
oxc_index: '5',
162+
});
163+
// No spurious changes for already-matching crates.
164+
expect(changes.find((c) => c.key === 'oxc_resolver')).toBeUndefined();
165+
expect(changes.find((c) => c.key === 'oxc_sourcemap')).toBeUndefined();
166+
});
167+
168+
test('is a no-op when versions already match', () => {
169+
const { content, changes } = syncCargoOxcVersions(mainCargo, mainCargo);
170+
expect(content).toBe(mainCargo);
171+
expect(changes).toEqual([]);
172+
});
173+
174+
test('only rewrites entries inside [workspace.dependencies]', () => {
175+
const withPatch = `${mainCargo}
176+
[patch.crates-io]
177+
# pinned override, must not be touched by the oxc sync
178+
oxc_ast = { git = "https://example.com/oxc", rev = "abc" }
179+
`;
180+
const { content } = syncCargoOxcVersions(withPatch, rolldownCargo);
181+
// The dependency entry is bumped...
182+
expect(content).toContain('oxc_ast = "0.135.0"');
183+
// ...but the [patch] git override is left intact.
184+
expect(content).toContain('oxc_ast = { git = "https://example.com/oxc", rev = "abc" }');
185+
});
186+
});

packages/tools/src/sync-remote-deps.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -957,6 +957,10 @@ export async function syncRemote() {
957957

958958
execCommand('pnpm install --no-frozen-lockfile', rootDir);
959959

960+
// Keep the root Cargo.toml oxc pins in lockstep with the vendored rolldown.
961+
log('Syncing Cargo.toml oxc versions with rolldown...');
962+
syncCargoOxcWithRolldown(rootDir);
963+
960964
// Merge package.json exports
961965
log('Merging package.json exports...');
962966

0 commit comments

Comments
 (0)