diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b8ef3f9fc..8a0ee6ebc 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -67,7 +67,22 @@ jobs: env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Extract release notes from CHANGELOG + id: changelog + shell: bash + run: | + VERSION="${GITHUB_REF#refs/tags/v}" + NOTES=$(awk "/^## \\[$VERSION\\]/{found=1; next} /^## \\[/{if(found) exit} found" gitnexus/CHANGELOG.md) + if [ -z "$NOTES" ]; then + echo "::warning::No CHANGELOG entry found for v$VERSION, falling back to auto-generated notes" + echo "fallback=true" >> "$GITHUB_OUTPUT" + else + echo "$NOTES" > /tmp/release-notes.md + echo "fallback=false" >> "$GITHUB_OUTPUT" + fi + - name: Create GitHub Release uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2 with: - generate_release_notes: true + body_path: ${{ steps.changelog.outputs.fallback == 'false' && '/tmp/release-notes.md' || '' }} + generate_release_notes: ${{ steps.changelog.outputs.fallback == 'true' }} diff --git a/gitnexus/package-lock.json b/gitnexus/package-lock.json index 6d6a958fd..b5a1a139e 100644 --- a/gitnexus/package-lock.json +++ b/gitnexus/package-lock.json @@ -16,7 +16,6 @@ "commander": "^12.0.0", "cors": "^2.8.5", "express": "^4.19.2", - "gitnexus-shared": "file:../gitnexus-shared", "glob": "^11.0.0", "graphology": "^0.25.4", "graphology-indices": "^0.17.0", @@ -50,6 +49,7 @@ "@types/node": "^20.0.0", "@types/uuid": "^10.0.0", "@vitest/coverage-v8": "^4.0.18", + "gitnexus-shared": "file:../gitnexus-shared", "tsx": "^4.0.0", "typescript": "^5.4.5", "vitest": "^4.0.18" @@ -65,6 +65,7 @@ }, "../gitnexus-shared": { "version": "1.0.0", + "dev": true, "devDependencies": { "typescript": "^6.0.2" } diff --git a/gitnexus/package.json b/gitnexus/package.json index 252bf0375..48e388b11 100644 --- a/gitnexus/package.json +++ b/gitnexus/package.json @@ -38,7 +38,7 @@ "vendor" ], "scripts": { - "build": "tsc", + "build": "node scripts/build.js", "serve": "tsx src/cli/index.ts serve", "dev": "tsx watch src/cli/index.ts", "test": "vitest run", @@ -46,11 +46,10 @@ "test:integration": "vitest run test/integration", "test:watch": "vitest", "test:coverage": "vitest run --coverage", - "prepare": "npm run build", + "prepare": "tsc", "prepack": "npm run build && chmod +x dist/cli/index.js" }, "dependencies": { - "gitnexus-shared": "file:../gitnexus-shared", "@huggingface/transformers": "^3.0.0", "@ladybugdb/core": "^0.15.2", "@modelcontextprotocol/sdk": "^1.0.0", @@ -87,6 +86,7 @@ "tree-sitter-swift": "^0.6.0" }, "devDependencies": { + "gitnexus-shared": "file:../gitnexus-shared", "@types/cli-progress": "^3.11.6", "@types/cors": "^2.8.17", "@types/express": "^4.17.21", diff --git a/gitnexus/scripts/build.js b/gitnexus/scripts/build.js new file mode 100644 index 000000000..d3e33bfb3 --- /dev/null +++ b/gitnexus/scripts/build.js @@ -0,0 +1,69 @@ +#!/usr/bin/env node +/** + * Build script that compiles gitnexus and inlines gitnexus-shared into the dist. + * + * Steps: + * 1. Build gitnexus-shared (tsc) + * 2. Build gitnexus (tsc) + * 3. Copy gitnexus-shared/dist → dist/_shared + * 4. Rewrite bare 'gitnexus-shared' specifiers → relative paths + */ +import { execSync } from 'node:child_process'; +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.resolve(__dirname, '..'); +const SHARED_ROOT = path.resolve(ROOT, '..', 'gitnexus-shared'); +const DIST = path.join(ROOT, 'dist'); +const SHARED_DEST = path.join(DIST, '_shared'); + +// ── 1. Build gitnexus-shared ─────────────────────────────────────── +console.log('[build] compiling gitnexus-shared…'); +execSync('npx tsc', { cwd: SHARED_ROOT, stdio: 'inherit' }); + +// ── 2. Build gitnexus ────────────────────────────────────────────── +console.log('[build] compiling gitnexus…'); +execSync('npx tsc', { cwd: ROOT, stdio: 'inherit' }); + +// ── 3. Copy shared dist ──────────────────────────────────────────── +console.log('[build] copying shared module into dist/_shared…'); +fs.cpSync(path.join(SHARED_ROOT, 'dist'), SHARED_DEST, { recursive: true }); + +// ── 4. Rewrite imports ───────────────────────────────────────────── +console.log('[build] rewriting gitnexus-shared imports…'); +let rewritten = 0; + +function rewriteFile(filePath) { + const content = fs.readFileSync(filePath, 'utf-8'); + if (!content.includes('gitnexus-shared')) return; + + const relDir = path.relative(path.dirname(filePath), SHARED_DEST); + // Always use posix separators and point to the package index + const relImport = relDir.split(path.sep).join('/') + '/index.js'; + + const updated = content + .replace(/from\s+['"]gitnexus-shared['"]/g, `from '${relImport}'`) + .replace(/import\(\s*['"]gitnexus-shared['"]\s*\)/g, `import('${relImport}')`); + + if (updated !== content) { + fs.writeFileSync(filePath, updated); + rewritten++; + } +} + +function walk(dir, extensions, cb) { + for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { + const full = path.join(dir, entry.name); + if (entry.isDirectory()) { + walk(full, extensions, cb); + } else if (extensions.some((ext) => entry.name.endsWith(ext))) { + cb(full); + } + } +} + +walk(DIST, ['.js', '.d.ts'], rewriteFile); + +console.log(`[build] done — rewrote ${rewritten} files.`);