diff --git a/docs/RELEASING.md b/docs/RELEASING.md index c71ab11..c5e55f1 100644 --- a/docs/RELEASING.md +++ b/docs/RELEASING.md @@ -13,8 +13,10 @@ npm publish needs 2FA. mise run publish-dry-run apps/ ``` -3. Publish from a clean `main` (runs `mise run check` first, then `pnpm publish`, then tags - `@`): +3. Publish from a clean `main`. The task checks the npm login first (`pnpm whoami`; if it + fails, it runs `pnpm login` and checks again), so an expired login stops it in seconds, not + after the test suite. Then it runs `mise run check`, `pnpm publish`, and tags + `@`: ```bash mise run publish apps/ diff --git a/mise.toml b/mise.toml index f3dc92b..995a20e 100644 --- a/mise.toml +++ b/mise.toml @@ -87,9 +87,9 @@ description = "Audit local capture surfaces and browser extensions (macOS/Linux) run = "bash apps/am-i-being-recorded/bin/am-i-being-recorded.sh" [tasks.publish] -description = "Publish one package to npm (2FA), then tag it. Usage: mise run publish apps/" -depends = ["check"] -run = "bash scripts/release.sh publish" +description = "Check the npm login, run the checks, publish one package to npm (2FA), then tag it. Usage: mise run publish apps/" +raw = true +run = ["bash scripts/release.sh login", { task = "check" }, "bash scripts/release.sh publish"] [tasks.publish-dry-run] description = "List the files one package would publish. Usage: mise run publish-dry-run apps/" diff --git a/scripts/release.sh b/scripts/release.sh index ec6fd35..d64634a 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -2,6 +2,7 @@ # Release one package from this monorepo to npm. The name and version come from the # package's own package.json, so one script serves every package. # +# scripts/release.sh login # make sure npm is logged in (pnpm login if not) # scripts/release.sh dry-run apps/ # list the files that would ship # scripts/release.sh publish apps/ # publish (npm asks for 2FA), then tag # @@ -13,13 +14,28 @@ set -euo pipefail cd "$(dirname "$0")/.." +registry=https://registry.npmjs.org/ + die() { echo "release.sh: $*" >&2 exit 1 } +# npm answers an upload without a valid login with 404, not 401, so check before publishing. +ensure_login() { + pnpm whoami --registry "$registry" >/dev/null 2>&1 && return + echo "release.sh: not logged in to npm; running pnpm login" >&2 + pnpm login --registry "$registry" + pnpm whoami --registry "$registry" >/dev/null 2>&1 || die "still not logged in to npm" +} + +if [[ ${1:-} == login ]]; then + ensure_login + exit +fi + [[ $# -eq 2 ]] || { - echo "usage: release.sh dry-run|publish " >&2 + echo "usage: release.sh login | dry-run|publish " >&2 exit 2 } action=$1 @@ -42,6 +58,7 @@ dry-run) (cd "$dir" && pnpm pack --dry-run) ;; publish) + ensure_login if [[ -n "$(pnpm view "$name@$version" version 2>/dev/null)" ]]; then die "$name@$version is already on npm; bump the version in $pkg" fi