mise.toml

  1# SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
  2#
  3# SPDX-License-Identifier: CC0-1.0
  4
  5[tools]
  6bun = "1.3"
  7
  8[tasks.fmt]
  9description = "Format all files with Biome"
 10run = "bun run fmt"
 11
 12[tasks.lint]
 13description = "Lint all files with Biome"
 14run = "bun run lint"
 15
 16[tasks.typecheck]
 17description = "Type-check all packages with TypeScript"
 18run = "bun run typecheck"
 19
 20[tasks.check]
 21description = "Format, lint, and type-check"
 22depends = ["fmt", "lint", "typecheck"]
 23
 24[tasks."release:bump"]
 25description = "Bump one or more package versions"
 26usage = '''
 27arg "<version>" help="SemVer increment or exact version"
 28arg "<packages>" help="Package selectors" var=#true var_min=1
 29flag "--preid <preid>" help="Prerelease identifier for pre* increments"
 30'''
 31shell = "bash -c"
 32run = '''
 33set -euo pipefail
 34
 35version=${usage_version:?}
 36preid=${usage_preid:-}
 37eval "packages=(${usage_packages:?})"
 38
 39exact_version_re='^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?$'
 40is_exact_version=false
 41if [[ "$version" =~ $exact_version_re ]]; then
 42	is_exact_version=true
 43fi
 44
 45case "$version" in
 46	patch|minor|major|prepatch|preminor|premajor|prerelease) ;;
 47	*)
 48		if [[ "$is_exact_version" != true ]]; then
 49			echo "Error: unsupported version '$version'" >&2
 50			echo "Use patch, minor, major, prepatch, preminor, premajor, prerelease, or an exact SemVer." >&2
 51			exit 1
 52		fi
 53		;;
 54esac
 55
 56if [[ -n "$preid" ]]; then
 57	case "$version" in
 58		prepatch|preminor|premajor|prerelease) ;;
 59		*)
 60			echo "Error: --preid only applies to prepatch, preminor, premajor, or prerelease" >&2
 61			exit 1
 62			;;
 63	esac
 64fi
 65
 66resolved_dirs=$(bash scripts/resolve-release-packages.bash "${packages[@]}")
 67mapfile -t dirs <<< "$resolved_dirs"
 68
 69if [[ "$is_exact_version" == true && -n "${dirs[1]:-}" ]]; then
 70	echo "Error: exact versions may only be applied to one package at a time" >&2
 71	exit 1
 72fi
 73
 74for dir in "${dirs[@]}"; do
 75	args=(pm version "$version" --no-git-tag-version)
 76	if [[ -n "$preid" ]]; then
 77		args+=(--preid "$preid")
 78	fi
 79	echo "Bumping $dir"
 80	(
 81		cd "$dir"
 82		bun "${args[@]}"
 83	)
 84done
 85'''
 86
 87[tasks."release:pack"]
 88description = "Check and dry-run npm package packing"
 89usage = '''
 90arg "<packages>" help="Package selectors" var=#true var_min=1
 91'''
 92shell = "bash -c"
 93run = '''
 94set -euo pipefail
 95
 96eval "packages=(${usage_packages:?})"
 97resolved_dirs=$(bash scripts/resolve-release-packages.bash "${packages[@]}")
 98mapfile -t dirs <<< "$resolved_dirs"
 99
100mise run check
101
102for dir in "${dirs[@]}"; do
103	echo "Packing $dir (dry run)"
104	bunx npm pack --dry-run "./$dir"
105done
106'''
107
108[tasks."release:publish"]
109description = "Check, dry-run, and publish npm packages"
110usage = '''
111arg "<packages>" help="Package selectors" var=#true var_min=1
112flag "--tag <tag>" help="npm dist-tag" default="latest"
113flag "--otp <otp>" help="One-time password for npm two-factor auth"
114'''
115shell = "bash -c"
116run = '''
117set -euo pipefail
118
119package_version() {
120	bun -e 'const fs = require("node:fs"); const path = require("node:path"); const pkg = JSON.parse(fs.readFileSync(path.join(process.argv[1], "package.json"), "utf8")); console.log(pkg.version);' "$1"
121}
122
123eval "packages=(${usage_packages:?})"
124tag=${usage_tag:?}
125otp=${usage_otp:-}
126resolved_dirs=$(bash scripts/resolve-release-packages.bash "${packages[@]}")
127mapfile -t dirs <<< "$resolved_dirs"
128
129if [[ -n "$otp" && -n "${dirs[1]:-}" ]]; then
130	echo "Error: --otp may only be used with one package at a time" >&2
131	echo "Use an npm automation token for multi-package publishing, or publish each package separately with a fresh OTP." >&2
132	exit 1
133fi
134
135for dir in "${dirs[@]}"; do
136	version=$(package_version "$dir")
137	if [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+- && "$tag" == latest ]]; then
138		echo "Error: refusing to publish prerelease $dir@$version with tag latest" >&2
139		echo "Use --tag beta or another prerelease dist-tag." >&2
140		exit 1
141	fi
142done
143
144mise run check
145
146publish_args=(--access public --tag "$tag")
147if [[ -n "$otp" ]]; then
148	publish_args+=(--otp "$otp")
149fi
150
151for dir in "${dirs[@]}"; do
152	echo "Publishing $dir (dry run)"
153	bunx npm publish --dry-run "${publish_args[@]}" "./$dir"
154done
155
156for dir in "${dirs[@]}"; do
157	echo "Publishing $dir"
158	bunx npm publish "${publish_args[@]}" "./$dir"
159done
160'''