Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 42 additions & 6 deletions scripts/sync-provider-models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
* pnpm tsx scripts/sync-provider-models.ts
*/

import { execFileSync } from 'node:child_process'
import { readFile, writeFile } from 'node:fs/promises'
import { dirname, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
Expand Down Expand Up @@ -496,6 +497,38 @@ function addToTypeMap(
return content.replace(pattern, () => `${match[1]}\n${newEntries}${match[2]}`)
}

// ---------------------------------------------------------------------------
// Git-based change detection
// ---------------------------------------------------------------------------

/**
* Detect packages with uncommitted changes by running `git diff`.
* This captures changes from ALL prior pipeline steps (e.g. convert-openrouter-models.ts)
* not just the models added by this script.
*/
function detectChangedPackages(): Set<string> {
const changed = new Set<string>()
try {
const diff = execFileSync(
'git',
['diff', 'HEAD', '--name-only', '--', 'packages/'],
{ encoding: 'utf-8', cwd: ROOT },
).trim()
if (!diff) return changed

for (const line of diff.split('\n')) {
// packages/typescript/ai-openrouter/... → @tanstack/ai-openrouter
const match = line.match(/^packages\/typescript\/([\w-]+)\//)
if (match) {
changed.add(`@tanstack/${match[1]}`)
}
}
} catch {
// git not available (e.g. running outside a repo) — fall back to empty set
}
Comment on lines +526 to +528
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Surface unexpected git diff failures here.

Returning an empty set for every execFileSync error makes the workflow quietly skip the changeset again when Git detection breaks for any reason other than an intentional local “not a repo” run. I’d at least warn on the fallback and fail loudly in CI.

🔧 Suggested tightening
-  } catch {
-    // git not available (e.g. running outside a repo) — fall back to empty set
+  } catch (error) {
+    if (process.env.GITHUB_ACTIONS === 'true') {
+      throw error
+    }
+    console.warn('Failed to detect changed packages via git diff:', error)
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/sync-provider-models.ts` around lines 526 - 528, The catch block that
swallows all execFileSync errors in scripts/sync-provider-models.ts should
distinguish expected "not a repo" cases from real failures: inside the catch
after the execFileSync(...) call, log the caught error (e.g., console.warn or
processLogger.warn) and only return the empty set when the error message
indicates a non-repo (match on "not a git repository" / exit code), otherwise
rethrow or exit non‑zero so CI fails; update the handler around the execFileSync
invocation (the try/catch that currently returns an empty set) to implement this
conditional logging-and-fail behavior.

return changed
}

// ---------------------------------------------------------------------------
// Main
// ---------------------------------------------------------------------------
Expand Down Expand Up @@ -672,20 +705,23 @@ async function main() {
// Record this run's timestamp for future age-based filtering
await writeLastRunTimestamp()

// Create changeset if any models were added
if (totalAdded > 0) {
await createChangeset(changedPackages)
// Detect all packages with uncommitted changes (includes changes from
// convert-openrouter-models.ts which runs before this script)
const allChangedPackages = detectChangedPackages()
for (const pkg of changedPackages) {
allChangedPackages.add(pkg)
}

if (allChangedPackages.size > 0) {
await createChangeset(allChangedPackages)
}
}

/**
* Create or update the sync-models changeset file.
* If one already exists, merges the package lists. Otherwise creates a new one.
* Always includes @tanstack/ai-openrouter since the convert script regenerates it.
*/
async function createChangeset(changedPackages: Set<string>) {
changedPackages.add('@tanstack/ai-openrouter')

const changesetDir = resolve(ROOT, '.changeset')
const { readdir } = await import('node:fs/promises')
const files = await readdir(changesetDir)
Expand Down
Loading