Skip to content
Merged
Show file tree
Hide file tree
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
43 changes: 43 additions & 0 deletions PUBLISH.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,21 @@

## Automated Publishing (Recommended)

### Version Packages (libpg-query)
```bash
pnpm run publish:versions
```

This interactive script will:
- Check for uncommitted changes (will error if any exist)
- Let you select which versions to publish (or all)
- Also includes the full package (@libpg-query/parser)
- Ask for version bump type (patch or minor only)
- Ask if you want to skip the build step (useful if already built)
- Always run tests (even if build is skipped)
- Publish each selected version
- Optionally promote pg17 to latest

### Types Packages
```bash
pnpm run publish:types
Expand Down Expand Up @@ -113,4 +128,32 @@ pnpm run publish:pkg
npm install libpg-query@pg17 # PostgreSQL 17 specific
npm install libpg-query@pg16 # PostgreSQL 16 specific
npm install libpg-query # Latest/default version
```

## Full Package (@libpg-query/parser)

### Quick Publish
```bash
cd full
pnpm version patch
git add . && git commit -m "release: bump @libpg-query/parser version"
pnpm build
pnpm test
pnpm publish --tag pg17
```

### Promote to latest (optional)
```bash
npm dist-tag add @libpg-query/parser@pg17 latest
```

### What it does
- Publishes `@libpg-query/parser` with tag `pg17`
- Currently based on PostgreSQL 17
- Includes full parser with all features

### Install published package
```bash
npm install @libpg-query/parser@pg17 # PostgreSQL 17 specific
npm install @libpg-query/parser # Latest version
```
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Built to power [pgsql-parser](https://github.com/pyramation/pgsql-parser), this
## 🚀 For Round-trip Codegen

> 🎯 **Want to parse + deparse (full round trip)?**
> We highly recommend using [`pgsql-parser`](https://github.com/launchql/pgsql-parser) which leverages a pure TypeScript deparser that has been battle-tested against 21,000+ SQL statements and is built on top of libpg-query.
> We highly recommend using [`pgsql-parser`](https://github.com/launchql/pgsql-parser) which leverages a pure TypeScript deparser that has been battle-tested against 23,000+ SQL statements and is built on top of libpg-query.

## Installation

Expand Down
2 changes: 1 addition & 1 deletion full/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Built to power [pgsql-parser](https://github.com/pyramation/pgsql-parser), this
## 🚀 For Round-trip Codegen

> 🎯 **Want to parse + deparse (full round trip)?**
> We highly recommend using [`pgsql-parser`](https://github.com/launchql/pgsql-parser) which leverages a pure TypeScript deparser that has been battle-tested against 21,000+ SQL statements and is built on top of libpg-query.
> We highly recommend using [`pgsql-parser`](https://github.com/launchql/pgsql-parser) which leverages a pure TypeScript deparser that has been battle-tested against 23,000+ SQL statements and is built on top of libpg-query.

## Installation

Expand Down
2 changes: 1 addition & 1 deletion full/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@libpg-query/parser",
"version": "17.5.1",
"version": "17.6.1",
"description": "The real PostgreSQL query parser",
"homepage": "https://github.com/launchql/libpg-query-node",
"main": "./wasm/index.cjs",
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"prepare:enums": "node scripts/prepare-enums.js",
"publish:types": "node scripts/publish-types.js",
"publish:enums": "node scripts/publish-enums.js",
"publish:versions": "node scripts/publish-versions.js",
"update:versions-types": "node scripts/update-versions-types.js"
},
"devDependencies": {
Expand Down
38 changes: 38 additions & 0 deletions scripts/publish-single-version.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/usr/bin/env node

const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');

const pkgPath = path.join(process.cwd(), 'package.json');

if (!fs.existsSync(pkgPath)) {
console.error('❌ No package.json found in current directory.');
process.exit(1);
}

const original = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
const publishMeta = original['x-publish'] || {};

const publishName = publishMeta.publishName || 'libpg-query';
const distTag = process.env.TAG || publishMeta.distTag || 'latest';

if (!original.name || !original.version) {
console.error('❌ package.json must include name and version');
process.exit(1);
}

const modified = { ...original, name: publishName };

try {
console.log(`📦 Publishing ${publishName}@${original.version} with tag '${distTag}'...`);
fs.writeFileSync(pkgPath, JSON.stringify(modified, null, 2));
// npm OK here since it's version, not dist/ package...
execSync(`npm publish --tag ${distTag}`, { stdio: 'inherit' });
console.log('✅ Publish complete.');
} catch (err) {
console.error('❌ Publish failed:', err.message);
} finally {
fs.writeFileSync(pkgPath, JSON.stringify(original, null, 2));
console.log('🔄 Restored original package.json');
}
232 changes: 207 additions & 25 deletions scripts/publish-versions.js
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,217 @@
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const readline = require('readline');

const pkgPath = path.join(process.cwd(), 'package.json');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});

if (!fs.existsSync(pkgPath)) {
console.error('❌ No package.json found in current directory.');
process.exit(1);
}
const question = (query) => new Promise((resolve) => rl.question(query, resolve));

const original = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
const publishMeta = original['x-publish'] || {};
async function main() {
console.log('🚀 Version Packages Publishing Tool\n');

const publishName = publishMeta.publishName || 'libpg-query';
const distTag = process.env.TAG || publishMeta.distTag || 'latest';
// Check for uncommitted changes
try {
execSync('git diff --quiet && git diff --cached --quiet');
} catch (error) {
console.error('❌ You have uncommitted changes. Please commit or stash them first.');
process.exit(1);
}

if (!original.name || !original.version) {
console.error('❌ package.json must include name and version');
process.exit(1);
}
// Get all version directories
const versionsDir = path.join(__dirname, '..', 'versions');
const versionDirs = fs.readdirSync(versionsDir)
.filter(dir => /^\d+$/.test(dir))
.sort((a, b) => parseInt(b) - parseInt(a)); // Sort descending

// Also check for full package
const fullPackagePath = path.join(__dirname, '..', 'full', 'package.json');
const hasFullPackage = fs.existsSync(fullPackagePath);

console.log('📦 Available packages:');
versionDirs.forEach(v => console.log(` - PostgreSQL ${v} (versions/${v})`));
if (hasFullPackage) {
console.log(` - Full package (./full) - PostgreSQL 17`);
}
console.log();

// Ask which versions to publish
const publishAll = await question('Publish all packages? (y/N): ');
let selectedVersions = [];
let includeFullPackage = false;

if (publishAll.toLowerCase() === 'y') {
selectedVersions = versionDirs;
includeFullPackage = hasFullPackage;
} else {
// Let user select versions
for (const version of versionDirs) {
const publish = await question(`Publish PostgreSQL ${version}? (y/N): `);
if (publish.toLowerCase() === 'y') {
selectedVersions.push(version);
}
}

if (hasFullPackage) {
const publishFull = await question(`Publish full package (PostgreSQL 17)? (y/N): `);
includeFullPackage = publishFull.toLowerCase() === 'y';
}
}

if (selectedVersions.length === 0 && !includeFullPackage) {
console.log('\n❌ No packages selected for publishing.');
rl.close();
return;
}

// Ask for version bump type
console.log('\n📈 Version bump type:');
console.log(' 1. patch (0.0.x)');
console.log(' 2. minor (0.x.0)');
const bumpType = await question('Select bump type (1 or 2): ');
const bump = bumpType === '2' ? 'minor' : 'patch';

const modified = { ...original, name: publishName };

try {
console.log(`📦 Publishing ${publishName}@${original.version} with tag '${distTag}'...`);
fs.writeFileSync(pkgPath, JSON.stringify(modified, null, 2));
execSync(`npm publish --tag ${distTag}`, { stdio: 'inherit' });
console.log('✅ Publish complete.');
} catch (err) {
console.error('❌ Publish failed:', err.message);
} finally {
fs.writeFileSync(pkgPath, JSON.stringify(original, null, 2));
console.log('🔄 Restored original package.json');
console.log(`\n📋 Will publish:`);
selectedVersions.forEach(v => console.log(` - PostgreSQL ${v} (${bump} bump)`));
if (includeFullPackage) {
console.log(` - Full package (${bump} bump)`);
}

// Ask about building
const skipBuild = await question('\nSkip build step? (y/N): ');
const shouldBuild = skipBuild.toLowerCase() !== 'y';

if (!shouldBuild) {
console.log('⚠️ Build step will be skipped. Make sure packages are already built!');
}

const confirm = await question('\nProceed? (y/N): ');
if (confirm.toLowerCase() !== 'y') {
console.log('❌ Publishing cancelled.');
rl.close();
return;
}

console.log('\n🔨 Starting publish process...\n');

// Process each selected version
for (const version of selectedVersions) {
console.log(`\n📦 Publishing PostgreSQL ${version}...`);
const versionPath = path.join(versionsDir, version);

try {
// Version bump
console.log(` 📝 Bumping version (${bump})...`);
execSync(`pnpm version ${bump}`, { cwd: versionPath, stdio: 'inherit' });

// Commit
console.log(` 💾 Committing version bump...`);
execSync(`git add package.json`, { cwd: versionPath });
execSync(`git commit -m "release: bump libpg-query v${version} version"`, { stdio: 'inherit' });

// Build (if not skipped)
if (shouldBuild) {
console.log(` 🔨 Building...`);
execSync('pnpm build', { cwd: versionPath, stdio: 'inherit' });
} else {
console.log(` ⏭️ Skipping build step`);
}

// Test (always run)
console.log(` 🧪 Running tests...`);
execSync('pnpm test', { cwd: versionPath, stdio: 'inherit' });

// Publish
console.log(` 📤 Publishing to npm...`);
execSync('pnpm run publish:pkg', { cwd: versionPath, stdio: 'inherit' });

console.log(` ✅ PostgreSQL ${version} published successfully!`);
} catch (error) {
console.error(` ❌ Failed to publish PostgreSQL ${version}:`, error.message);
const continuePublish = await question('Continue with other versions? (y/N): ');
if (continuePublish.toLowerCase() !== 'y') {
rl.close();
process.exit(1);
}
}
}

// Process full package if selected
if (includeFullPackage) {
console.log(`\n📦 Publishing full package...`);
const fullPath = path.join(__dirname, '..', 'full');

try {
// Version bump
console.log(` 📝 Bumping version (${bump})...`);
execSync(`pnpm version ${bump}`, { cwd: fullPath, stdio: 'inherit' });

// Commit
console.log(` 💾 Committing version bump...`);
execSync(`git add package.json`, { cwd: fullPath });
execSync(`git commit -m "release: bump @libpg-query/parser version"`, { stdio: 'inherit' });

// Build (if not skipped)
if (shouldBuild) {
console.log(` 🔨 Building...`);
execSync('pnpm build', { cwd: fullPath, stdio: 'inherit' });
} else {
console.log(` ⏭️ Skipping build step`);
}

// Test (always run)
console.log(` 🧪 Running tests...`);
execSync('pnpm test', { cwd: fullPath, stdio: 'inherit' });

// Publish with pg17 tag
console.log(` 📤 Publishing to npm with pg17 tag...`);
// use npm so staged changes are OK
execSync('npm publish --tag pg17', { cwd: fullPath, stdio: 'inherit' });

console.log(` ✅ Full package published successfully with pg17 tag!`);
} catch (error) {
console.error(` ❌ Failed to publish full package:`, error.message);
}
}

// Ask about promoting to latest
if (selectedVersions.includes('17') || includeFullPackage) {
console.log('\n🏷️ Tag Management');

if (selectedVersions.includes('17')) {
const promoteVersions = await question('Promote libpg-query@pg17 to latest? (y/N): ');
if (promoteVersions.toLowerCase() === 'y') {
try {
execSync('npm dist-tag add libpg-query@pg17 latest', { stdio: 'inherit' });
console.log('✅ libpg-query@pg17 promoted to latest');
} catch (error) {
console.error('❌ Failed to promote tag:', error.message);
}
}
}

if (includeFullPackage) {
const promoteFullPackage = await question('Promote @libpg-query/parser@pg17 to latest? (y/N): ');
if (promoteFullPackage.toLowerCase() === 'y') {
try {
execSync('npm dist-tag add @libpg-query/parser@pg17 latest', { stdio: 'inherit' });
console.log('✅ @libpg-query/parser@pg17 promoted to latest');
} catch (error) {
console.error('❌ Failed to promote tag:', error.message);
}
}
}
}

console.log('\n✨ Publishing complete!');
rl.close();
}

main().catch(error => {
console.error('❌ Error:', error);
rl.close();
process.exit(1);
});
2 changes: 1 addition & 1 deletion versions/13/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Built to power [pgsql-parser](https://github.com/pyramation/pgsql-parser), this
## 🚀 For Round-trip Codegen

> 🎯 **Want to parse + deparse (full round trip)?**
> We highly recommend using [`pgsql-parser`](https://github.com/launchql/pgsql-parser) which leverages a pure TypeScript deparser that has been battle-tested against 21,000+ SQL statements and is built on top of libpg-query.
> We highly recommend using [`pgsql-parser`](https://github.com/launchql/pgsql-parser) which leverages a pure TypeScript deparser that has been battle-tested against 23,000+ SQL statements and is built on top of libpg-query.

## Installation

Expand Down
Loading