-
-
Save reilg/e5f4c51772343793505f64311382b9a0 to your computer and use it in GitHub Desktop.
Publish a new version of an npm package
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# | |
# Publish a new version of an npm package. | |
# | |
# - Runs linter, tests | |
# - Asks if next version is major, minor or patch | |
# - Calculates the next version from this | |
# - Checks that the CHANGELOG references the new version | |
# - Tags/publishes the new version via git/npm | |
# | |
# Download: | |
# | |
# curl -s https://gist.githubusercontent.com/shuckster/246e3d5f98d51d20cdf00ade25029d04/raw/publish.sh -o publish.sh | |
# chmod +x ./publish.sh | |
# echo "publish.sh" >> .gitignore | |
# | |
# Written by Conan: https://gist.github.com/shuckster/246e3d5f98d51d20cdf00ade25029d04 | |
# | |
_TEST_="pnpm run test" | |
_LINT_="pnpm run lint" | |
_VERSION_="pnpm version" | |
_BUILD_="pnpm run build:all" | |
_DRY_RUN_="pnpm publish --dry-run" | |
_PUBLISH_="pnpm publish" | |
_GIT_='git' | |
main() | |
{ | |
lint_and_test | |
prompt_for_next_semversion | |
calculate_next_semversion | |
confirm_changelog_has_semversion | |
set_package_semversion_and_validate | |
rebuild_and_dry_run_publish | |
publish_and_push | |
} | |
lint_and_test() | |
{ | |
$_LINT_ || bail "Linting failed" | |
$_TEST_ || bail "Tests failed" | |
} | |
prompt_for_next_semversion() | |
{ | |
current_version=$(grep version package.json|awk 'BEGIN { FS="\"" } { print $4 }') | |
major_v=$(echo "${current_version}"|awk 'BEGIN { FS="." } { print $1 }') | |
minor_v=$(echo "${current_version}"|awk 'BEGIN { FS="." } { print $2 }') | |
patch_v=$(echo "${current_version}"|awk 'BEGIN { FS="." } { print $3 }') | |
minor_space=$(echo "${minor_v}"|sed 's/[0-9\.]/ /g') | |
minor_dash=$(echo "${minor_v}"|sed 's/[0-9\.]/─/g') | |
patch_space=$(echo "${patch_v}"|sed 's/[0-9\.]/ /g') | |
patch_dash=$(echo "${patch_v}"|sed 's/[0-9\.]/─/g') | |
echo "" | |
echo "Current version: ${current_version}" | |
echo " ^${minor_space}^${patch_space}^" | |
echo " ┌──────────────┘${minor_space}│${patch_space}│" | |
echo " │ ┌────────${minor_dash}┘${patch_space}│" | |
echo " │ │ ┌─${minor_dash}─${patch_dash}┘" | |
echo " ─┴─ ─┴─ ─┴─" | |
printf "major, minor, patch?: " | |
read -r semver | |
case ${semver} in | |
major|minor|patch) : ;; | |
*) | |
bail "Please specify either major, minor or patch" | |
;; | |
esac | |
} | |
calculate_next_semversion() | |
{ | |
if [ "${semver}" = "major" ]; then : $((major_v+=1)); minor_v=0; patch_v=0; fi | |
if [ "${semver}" = "minor" ]; then : $((minor_v+=1)); patch_v=0; fi | |
if [ "${semver}" = "patch" ]; then : $((patch_v+=1)); fi | |
next_version="${major_v}.${minor_v}.${patch_v}" | |
} | |
confirm_changelog_has_semversion() | |
{ | |
line_padding=$(echo "${next_version}"|sed 's/[0-9\.]/─/g') | |
echo "" | |
echo "┌─────────────────────────────────${line_padding}──┐" | |
echo "│ Prep CHANGELOG.md for version: ${next_version} │" | |
echo "└─────────────────────────────────${line_padding}──┘" | |
echo "" | |
if ! grep "## \\[${next_version}\\]" CHANGELOG.md | |
then | |
bail "It doesn't look like you've done that yet..." | |
fi | |
prompter "Did you do that?" "Yes, I did already!" | |
} | |
set_package_semversion_and_validate() | |
{ | |
$_VERSION_ "${semver}" || bail "Could not update package version" | |
new_version=$(grep version package.json|awk 'BEGIN { FS="\"" } { print $4 }') | |
if [ "${new_version}" != "${next_version}" ] | |
then | |
bail "Version in package.json (${new_version}) doesn't match calculated version (${next_version})" | |
fi | |
} | |
rebuild_and_dry_run_publish() | |
{ | |
# Rebuild after `npm version` to put version-info into bundle | |
$_BUILD_ || bail "Build failed" | |
# Skip pre-commit hooks as we've done that in the first step | |
$_GIT_ add . | |
$_GIT_ commit -m "Published ${new_version}" -n | |
$_DRY_RUN_ || bail "Dry run failed" | |
prompter "Does the dry-run look good?" "Yes, not too bad!" | |
} | |
publish_and_push() | |
{ | |
$_PUBLISH_ || bail "Publish failed" | |
$_GIT_ push | |
$_GIT_ push origin --tags | |
} | |
prompter() | |
{ | |
confirm_text="${2}" | |
printf "${1} [%s]: " "${confirm_text}" | |
read -r confirm | |
echo "" | |
if [ "${confirm}" != "${confirm_text}" ] | |
then | |
bail "That wasn't it..." | |
fi | |
} | |
bail() | |
{ | |
echo "" | |
echo "[BAIL] :: $1" | |
echo "" | |
exit 1 | |
} | |
main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment