diff --git a/.npmrc b/.npmrc index 449691b..89ea32a 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +1,5 @@ -save-exact=true \ No newline at end of file +save-exact=true +# Link internal @parallax/* packages from the workspace by version (they are +# unpublished and only bundled into parallax-cli), so package.json can pin +# concrete versions instead of the workspace:* protocol. +link-workspace-packages=true \ No newline at end of file diff --git a/package.json b/package.json index 34afe18..e070979 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "lint:fix": "pnpm --filter './packages/*' -r lint:fix && pnpm exec eslint eslint.config.js --fix", "parallax": "NODE_ENV=dev pnpm --filter parallax-cli start", "clean": "rm -rf packages/orchestrator/parallax.db packages/orchestrator/workspaces", + "version:set": "node scripts/set-version.mjs", "release:pack": "pnpm --filter parallax-cli pack:tarball", "release:publish": "pnpm --dir packages/cli publish:package" }, diff --git a/packages/cli/package.json b/packages/cli/package.json index bc87032..8d5c7aa 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -36,10 +36,12 @@ "dependencies": { "@clack/prompts": "1.4.0", "@fastify/cors": "11.2.0", - "@parallax/common": "workspace:*", - "@parallax/orchestrator": "workspace:*", - "@parallax/slack": "workspace:*", - "@parallax/ui": "workspace:*", + "@parallax/common": "0.1.0", + "@parallax/orchestrator": "0.1.0", + "@parallax/slack": "0.1.0", + "@parallax/ui": "0.1.0", + "@slack/bolt": "^4.0.0", + "@slack/web-api": "^7.0.0", "chalk": "4", "fastify": "5.7.4", "log-update": "7.1.0", diff --git a/packages/cli/scripts/prepare-package.mjs b/packages/cli/scripts/prepare-package.mjs index 710b3da..d19eec0 100644 --- a/packages/cli/scripts/prepare-package.mjs +++ b/packages/cli/scripts/prepare-package.mjs @@ -1,5 +1,5 @@ import fs from 'node:fs/promises' -import { lstatSync, readlinkSync } from 'node:fs' +import { lstatSync, readlinkSync, readFileSync } from 'node:fs' import path from 'node:path' import { execFileSync } from 'node:child_process' import { fileURLToPath } from 'node:url' @@ -51,8 +51,27 @@ const bundledPackages = [ type: 'module', }, }, + { + name: '@parallax/slack', + sourceDir: path.join(workspaceRoot, 'packages/slack'), + packageJson: { + name: '@parallax/slack', + version: '0.0.4', + type: 'module', + }, + }, ] +// Pin each bundled package to its real workspace version so the published +// package.json, the flattened bundled package.json, and the rewritten cli +// dependency ranges all stay consistent across releases. +for (const metadata of bundledPackages) { + const { version } = JSON.parse( + readFileSync(path.join(metadata.sourceDir, 'package.json'), 'utf8') + ) + metadata.packageJson.version = version +} + function runPnpm(args) { execFileSync('pnpm', ['--dir', workspaceRoot, ...args], { stdio: 'inherit', @@ -120,6 +139,7 @@ async function main() { '@parallax/common': bundledPackages[0].packageJson.version, '@parallax/orchestrator': bundledPackages[1].packageJson.version, '@parallax/ui': bundledPackages[2].packageJson.version, + '@parallax/slack': bundledPackages[3].packageJson.version, }, } await fs.writeFile(cliPackageJsonPath, JSON.stringify(rewrittenCliPackageJson, null, 2) + '\n') diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4a6c40c..d3b1db9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -54,17 +54,23 @@ importers: specifier: 11.2.0 version: 11.2.0 '@parallax/common': - specifier: workspace:* + specifier: 0.1.0 version: link:../common '@parallax/orchestrator': - specifier: workspace:* + specifier: 0.1.0 version: link:../orchestrator '@parallax/slack': - specifier: workspace:* + specifier: 0.1.0 version: link:../slack '@parallax/ui': - specifier: workspace:* + specifier: 0.1.0 version: link:../ui + '@slack/bolt': + specifier: ^4.0.0 + version: 4.7.2(@types/express@5.0.6) + '@slack/web-api': + specifier: ^7.0.0 + version: 7.15.2 chalk: specifier: '4' version: 4.1.2 diff --git a/scripts/set-version.mjs b/scripts/set-version.mjs new file mode 100644 index 0000000..5854318 --- /dev/null +++ b/scripts/set-version.mjs @@ -0,0 +1,51 @@ +import fs from 'node:fs' +import path from 'node:path' +import { fileURLToPath } from 'node:url' + +// Sets a single version across the whole workspace: the root package, every +// package under packages/*, and the internal @parallax/* dependency pins in the +// published cli package. Keeping these in lockstep is required because the +// @parallax/* packages are unpublished — the cli links them from the workspace +// by version (link-workspace-packages=true), so a stale pin would fall back to +// the npm registry and fail to resolve. +// +// Usage: node scripts/set-version.mjs + +const __dirname = path.dirname(fileURLToPath(import.meta.url)) +const workspaceRoot = path.resolve(__dirname, '..') + +const version = process.argv[2] +if (!version || !/^\d+\.\d+\.\d+(-[\w.]+)?$/.test(version)) { + console.error(`Usage: node scripts/set-version.mjs \nGot: ${version ?? '(none)'}`) + process.exit(1) +} + +const packagesDir = path.join(workspaceRoot, 'packages') +const packageJsonPaths = [ + path.join(workspaceRoot, 'package.json'), + ...fs + .readdirSync(packagesDir) + .map((name) => path.join(packagesDir, name, 'package.json')) + .filter((p) => fs.existsSync(p)), +] + +const internalPrefix = '@parallax/' + +for (const pkgPath of packageJsonPaths) { + const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')) + pkg.version = version + + // Re-pin any non-workspace internal dependency ranges to the new version. + for (const field of ['dependencies', 'devDependencies', 'peerDependencies']) { + const deps = pkg[field] + if (!deps) continue + for (const name of Object.keys(deps)) { + if (name.startsWith(internalPrefix) && !deps[name].startsWith('workspace:')) { + deps[name] = version + } + } + } + + fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n') + console.log(`${path.relative(workspaceRoot, pkgPath)} -> ${version}`) +}