publish.ts 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. #!/usr/bin/env bun
  2. import { $ } from "bun"
  3. import pkg from "../package.json"
  4. import { Script } from "@opencode-ai/script"
  5. import { fileURLToPath } from "url"
  6. import { UpdateArtifact } from "../../../script/update-artifact"
  7. const dir = fileURLToPath(new URL("..", import.meta.url))
  8. process.chdir(dir)
  9. async function published(name: string, version: string) {
  10. return (await $`npm view ${name}@${version} version`.nothrow()).exitCode === 0
  11. }
  12. async function publish(dir: string, name: string, version: string) {
  13. if (process.platform !== "win32") await $`chmod -R 755 .`.cwd(dir)
  14. if (await published(name, version)) return console.log(`already published ${name}@${version}`)
  15. await $`bun pm pack`.cwd(dir)
  16. await $`npm publish *.tgz --access public --tag ${Script.channel}`.cwd(dir)
  17. }
  18. async function publishDistribution(input: { root: string; name: string; binary: string; packagePrefix: string }) {
  19. const binaries: Record<string, string> = {}
  20. for (const filepath of new Bun.Glob("*/package.json").scanSync({ cwd: input.root })) {
  21. const item = await Bun.file(`${input.root}/${filepath}`).json()
  22. if (!item.name.startsWith(input.packagePrefix)) continue
  23. binaries[item.name] = item.version
  24. }
  25. console.log(input.name, "binaries", binaries)
  26. const versions = new Set(Object.values(binaries))
  27. if (versions.size > 1) throw new Error(`Binary package versions do not match for ${input.name}`)
  28. const version = versions.values().next().value
  29. if (!version) throw new Error(`No binary packages found for ${input.name}`)
  30. await $`mkdir -p ${input.root}/${input.name}/bin`
  31. await $`cp ./script/postinstall.mjs ${input.root}/${input.name}/postinstall.mjs`
  32. await Bun.file(`${input.root}/${input.name}/bin/${input.binary}.exe`).write(
  33. [
  34. `echo "Error: ${input.name}'s postinstall script was not run." >&2`,
  35. 'echo "" >&2',
  36. 'echo "This occurs when installation scripts are disabled." >&2',
  37. 'echo "Run the package postinstall script or reinstall with scripts enabled." >&2',
  38. "exit 1",
  39. "",
  40. ].join("\n"),
  41. )
  42. await Bun.file(`${input.root}/${input.name}/package.json`).write(
  43. JSON.stringify(
  44. {
  45. name: input.name,
  46. bin: { [input.binary]: `./bin/${input.binary}.exe` },
  47. scripts: { postinstall: "node ./postinstall.mjs" },
  48. version,
  49. license: pkg.license,
  50. repository: { type: "git", url: "git+https://github.com/anomalyco/opencode.git" },
  51. os: ["darwin", "linux", "win32"],
  52. cpu: ["arm64", "x64"],
  53. optionalDependencies: binaries,
  54. },
  55. null,
  56. 2,
  57. ),
  58. )
  59. await Promise.all(
  60. Object.entries(binaries).map(([name, version]) =>
  61. publish(`${input.root}/${name.replace("@opencode-ai/", "")}`, name, version),
  62. ),
  63. )
  64. await publish(`${input.root}/${input.name}`, input.name, version)
  65. }
  66. await publishDistribution({
  67. root: "./dist",
  68. name: pkg.name,
  69. binary: "opencode2",
  70. packagePrefix: "@opencode-ai/cli-",
  71. })
  72. await publishDistribution({
  73. root: "./dist/node",
  74. name: "opencode-node",
  75. binary: "opencode2-node",
  76. packagePrefix: "@opencode-ai/cli-node-",
  77. })
  78. await UpdateArtifact.publish({
  79. channel: Script.channel,
  80. name: "cli",
  81. distribution: "npm",
  82. version: Script.version,
  83. metadata: {},
  84. })