diff --git a/scripts/publish.js b/scripts/publish.js index fb2ab34e6bc06..62f2217b752bf 100644 --- a/scripts/publish.js +++ b/scripts/publish.js @@ -1,59 +1,58 @@ const semver = require('semver') const log = require('proc-log') const pacote = require('pacote') -const { run, git, npm, pkg, spawn } = require('./util.js') +const { run, git, npm, pkg: cli, spawn } = require('./util.js') const resetdeps = () => npm('run', 'resetdeps') const op = () => spawn('op', 'item', 'get', 'npm', '--otp', { out: true, ok: true }) -const TAGS = { - // cli is always published to next-MAJOR - root: (v) => ({ tag: `next-${semver.major(v)}` }), - // workspaces are always published to latest, except prereleases - workspace: () => ({ tag: 'latest', preTag: 'prerelease' }), +const getVersion = async (s) => { + const mani = await pacote.manifest(s, { preferOnline: true }) + return mani.version +} +const getLatest = async (s) => { + const pack = await pacote.packument(s, { preferOnline: true }) + return pack['dist-tags'].latest +} + +const TAG = { + cli: ({ version }) => `next-${semver.major(version)}`, + workspace: async ({ name, version }) => { + const { prerelease, major } = semver.parse(version) + if (prerelease.length) { + return 'prerelease' + } + if (major === await getLatest(name).then(v => semver.major(v))) { + return 'latest' + } + return 'backport' + }, } -const needsPublish = async ({ pkg: { private, name, version }, force, tags: getTags }) => { +const needsPublish = async ({ private, name, version }, { force, getTag }) => { if (private) { return } - const tags = getTags(version) - const tag = semver.parse(version).prerelease.length && tags.preTag - ? tags.preTag - : tags.tag - - if (force) { - return tag - } - - const mani = await pacote.manifest(`${name}@${tag}`, { preferOnline: true }) - if (version !== mani.version) { + const tag = await getTag({ name, version }) + if (force || version !== await getVersion(`${name}@${tag}`)) { return tag } } -const getPublishes = async ({ force }) => { +const getPublishes = async (opts) => { const publish = [] - for (const { name, pkg: ws } of await pkg.mapWorkspaces()) { + for (const { name, pkg } of await cli.mapWorkspaces()) { publish.push({ workspace: name, - tag: await needsPublish({ - force, - pkg: ws, - tags: TAGS.workspace, - }), + tag: await needsPublish(pkg, { ...opts, getTag: TAG.workspace }), }) } publish.push({ - tag: await needsPublish({ - force, - pkg, - tags: TAGS.root, - }), + tag: await needsPublish(cli, { ...opts, getTag: TAG.cli }), }) return publish.filter(p => p.tag)