Repository navigation
fix(desktop): align Tauri plugin Rust/npm versions, add version-parity CI guard #678
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 1 commit
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
4a043c6
fix(desktop): align Tauri plugin Rust/npm versions, add version-parit…
qnbs cfa032a
fix(desktop): compare resolved lockfile versions across the whole wor…
qnbs ea6aa67
fix(desktop): reduce complexity/duplication flagged by CodeScene on t…
qnbs 92b2045
fix(desktop): resolve duplicate Cargo.lock crate versions via direct-…
qnbs 1a435ab
fix(desktop): validate qualified Cargo.lock references, cover all rea…
qnbs ba0855a
fix(desktop): require direct-dependency membership, check every depen…
qnbs 8535778
fix(desktop): flatten resolvedCargoPluginVersions, consolidate remain…
qnbs f7eeda1
test(desktop): fix a test-fidelity gap the direct-dependency requirem…
qnbs e882aee
test(desktop): consolidate Tauri plugin-parity single-importer cases
qnbs 52f14d1
docs(ci): document the Tauri plugin parity gate; trim redundant test …
qnbs File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| export function findTauriPluginVersionMismatches( | ||
| cargoLock: string, | ||
| pkg: { dependencies?: Record<string, string> }, | ||
| ): string[]; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| #!/usr/bin/env node | ||
| /** | ||
| * Verify each Tauri plugin's Rust crate (src-tauri/Cargo.lock) and coupled npm package | ||
| * (package.json) share the same major.minor line. | ||
| * Run via ci:prepush or manually: | ||
| * node scripts/check-tauri-plugin-versions.mjs | ||
| */ | ||
| // QNBS-v3: tauri build rejects this mismatch too, but only inside the slow, tag-triggered, cross-platform release workflow — mirrors that check cheaply for regular CI (found live: v1.28.5's Rust-only plugin bump via #661 broke every platform's release build). | ||
| import fs from 'node:fs'; | ||
| import path from 'node:path'; | ||
| import { fileURLToPath } from 'node:url'; | ||
|
|
||
| const __dirname = path.dirname(fileURLToPath(import.meta.url)); | ||
| const root = path.join(__dirname, '..'); | ||
|
|
||
| const cargoLockPath = path.join(root, 'src-tauri', 'Cargo.lock'); | ||
| const pkgPath = path.join(root, 'package.json'); | ||
|
cubic-dev-ai[bot] marked this conversation as resolved.
Outdated
|
||
|
|
||
| // QNBS-v3: only Tauri plugins with a corresponding @tauri-apps/plugin-* npm package are coupled — tauri-plugin-log/window-state/deep-link/single-instance have no JS-side counterpart to drift against. | ||
|
qnbs marked this conversation as resolved.
Outdated
|
||
| const PLUGIN_PAIRS = [ | ||
| ['tauri-plugin-dialog', '@tauri-apps/plugin-dialog'], | ||
| ['tauri-plugin-fs', '@tauri-apps/plugin-fs'], | ||
| ['tauri-plugin-http', '@tauri-apps/plugin-http'], | ||
| ['tauri-plugin-notification', '@tauri-apps/plugin-notification'], | ||
| ['tauri-plugin-process', '@tauri-apps/plugin-process'], | ||
| ['tauri-plugin-shell', '@tauri-apps/plugin-shell'], | ||
| ['tauri-plugin-updater', '@tauri-apps/plugin-updater'], | ||
| ]; | ||
|
|
||
| function resolvedCargoVersion(cargoLock, crateName) { | ||
| const match = cargoLock.match(new RegExp(`name = "${crateName}"\\nversion = "([^"]+)"`)); | ||
| return match ? match[1] : null; | ||
|
qnbs marked this conversation as resolved.
Outdated
|
||
| } | ||
|
|
||
| function majorMinor(version) { | ||
| const match = version.match(/^(\d+)\.(\d+)/); | ||
| return match ? `${match[1]}.${match[2]}` : null; | ||
| } | ||
|
|
||
| export function findTauriPluginVersionMismatches(cargoLock, pkg) { | ||
| const findings = []; | ||
| for (const [crateName, npmName] of PLUGIN_PAIRS) { | ||
| const rustVersion = resolvedCargoVersion(cargoLock, crateName); | ||
| const npmRange = pkg.dependencies?.[npmName]; | ||
|
qnbs marked this conversation as resolved.
Outdated
|
||
| if (!rustVersion || !npmRange) continue; | ||
| const npmVersion = npmRange.replace(/^[\^~]/, ''); | ||
|
qnbs marked this conversation as resolved.
Outdated
cubic-dev-ai[bot] marked this conversation as resolved.
Outdated
cubic-dev-ai[bot] marked this conversation as resolved.
Outdated
qnbs marked this conversation as resolved.
Outdated
|
||
| if (majorMinor(rustVersion) !== majorMinor(npmVersion)) { | ||
|
sourcery-ai[bot] marked this conversation as resolved.
Outdated
|
||
| findings.push( | ||
| `${crateName} (Rust ${rustVersion}) vs ${npmName} (npm ${npmVersion}) — major/minor mismatch, "pnpm exec tauri build" rejects this`, | ||
| ); | ||
| } | ||
| } | ||
| return findings; | ||
| } | ||
|
|
||
| function main() { | ||
| const cargoLock = fs.readFileSync(cargoLockPath, 'utf8'); | ||
| const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')); | ||
| const findings = findTauriPluginVersionMismatches(cargoLock, pkg); | ||
| if (findings.length > 0) { | ||
| process.stderr.write( | ||
| `[tauri-plugin-versions] MISMATCH — ${findings.length} finding(s):\n${findings.map((f) => ` - ${f}`).join('\n')}\n`, | ||
| ); | ||
| process.exit(1); | ||
| } | ||
| process.stdout.write( | ||
| `[tauri-plugin-versions] OK — ${PLUGIN_PAIRS.length} plugin pairs checked, all major.minor-aligned.\n`, | ||
| ); | ||
| } | ||
|
|
||
| if (path.resolve(process.argv[1] ?? '') === fileURLToPath(import.meta.url)) main(); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| // @vitest-environment node | ||
| import { describe, expect, it } from 'vitest'; | ||
| import { findTauriPluginVersionMismatches } from '../../scripts/check-tauri-plugin-versions.mjs'; | ||
|
|
||
| function cargoLockEntry(crateName: string, version: string): string { | ||
| return `[[package]]\nname = "${crateName}"\nversion = "${version}"\nsource = "registry+https://github.com/rust-lang/crates.io-index"\n`; | ||
| } | ||
|
|
||
| describe('findTauriPluginVersionMismatches', () => { | ||
| it('reports nothing when every plugin pair shares the same major.minor', () => { | ||
| const cargoLock = cargoLockEntry('tauri-plugin-http', '2.6.0'); | ||
| const pkg = { dependencies: { '@tauri-apps/plugin-http': '^2.6.3' } }; | ||
| expect(findTauriPluginVersionMismatches(cargoLock, pkg)).toEqual([]); | ||
| }); | ||
|
|
||
| // QNBS-v3: reproduces the live v1.28.5 release-build failure — Rust bumped via a Dependabot PR without a matching npm bump. | ||
| it('flags a Rust-ahead-of-npm minor-version mismatch, reproducing the v1.28.5 release failure', () => { | ||
| const cargoLock = | ||
| cargoLockEntry('tauri-plugin-http', '2.6.0') + | ||
| cargoLockEntry('tauri-plugin-notification', '2.4.0'); | ||
| const pkg = { | ||
| dependencies: { | ||
| '@tauri-apps/plugin-http': '^2.5.9', | ||
| '@tauri-apps/plugin-notification': '^2.3.3', | ||
| }, | ||
| }; | ||
| const findings = findTauriPluginVersionMismatches(cargoLock, pkg); | ||
| expect(findings).toHaveLength(2); | ||
| expect(findings[0]).toContain('tauri-plugin-http'); | ||
| expect(findings[1]).toContain('tauri-plugin-notification'); | ||
| }); | ||
|
|
||
| it('flags an npm-ahead-of-Rust minor-version mismatch too', () => { | ||
| const cargoLock = cargoLockEntry('tauri-plugin-updater', '2.9.0'); | ||
| const pkg = { dependencies: { '@tauri-apps/plugin-updater': '^2.11.0' } }; | ||
| const findings = findTauriPluginVersionMismatches(cargoLock, pkg); | ||
| expect(findings).toHaveLength(1); | ||
| expect(findings[0]).toContain('tauri-plugin-updater'); | ||
| }); | ||
|
|
||
| it('ignores a plugin with no npm counterpart declared', () => { | ||
| const cargoLock = cargoLockEntry('tauri-plugin-log', '2.7.0'); | ||
| const pkg = { dependencies: {} }; | ||
| expect(findTauriPluginVersionMismatches(cargoLock, pkg)).toEqual([]); | ||
| }); | ||
|
|
||
| it('ignores an npm package with no resolved Rust crate in Cargo.lock', () => { | ||
| const cargoLock = ''; | ||
| const pkg = { dependencies: { '@tauri-apps/plugin-http': '^2.6.0' } }; | ||
| expect(findTauriPluginVersionMismatches(cargoLock, pkg)).toEqual([]); | ||
| }); | ||
|
|
||
| it('tolerates a patch-version difference within the same major.minor', () => { | ||
| const cargoLock = cargoLockEntry('tauri-plugin-dialog', '2.7.1'); | ||
| const pkg = { dependencies: { '@tauri-apps/plugin-dialog': '^2.7.0' } }; | ||
| expect(findTauriPluginVersionMismatches(cargoLock, pkg)).toEqual([]); | ||
| }); | ||
| }); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.