web/tools/release

197 lines
3.8 KiB
Text
Raw Normal View History

#!/usr/bin/env bash
#
# Requires: Git, NPM and RubyGems
set -eu
opt_pre=false # option for bump gem version
opt_pkg=false # option for building gem package
MAIN_BRANCH="master"
RELEASE_BRANCH="production"
GEM_SPEC="jekyll-theme-chirpy.gemspec"
NODE_SPEC="package.json"
CHANGELOG="docs/CHANGELOG.md"
CONFIG="_config.yml"
JS_DIST="assets/js/dist"
FILES=(
"$GEM_SPEC"
"$NODE_SPEC"
"$CHANGELOG"
"$CONFIG"
)
TOOLS=(
"git"
"npm"
"gem"
)
2022-02-14 18:59:17 +03:00
help() {
echo -e "A tool to release new version Chirpy gem.\nThis tool will:"
echo " 1. Build a new gem and publish it to RubyGems.org"
echo " 2. Merge the release branch into the default branch"
2022-02-14 18:59:17 +03:00
echo
echo "Usage:"
echo " bash ./tools/release [options]"
2022-02-14 18:59:17 +03:00
echo
echo "Options:"
echo " --prepare Preparation for release"
echo " -p, --package Build a gem package only, for local packaging in case of auto-publishing failure"
echo " -h, --help Display this help message"
2022-02-14 18:59:17 +03:00
}
_check_cli() {
for i in "${!TOOLS[@]}"; do
cli="${TOOLS[$i]}"
if ! command -v "$cli" &>/dev/null; then
echo "> Command '$cli' not found!"
exit 1
fi
done
}
_check_git() {
# ensure that changes have been committed
if [[ -n $(git status . -s) ]]; then
echo "> Abort: Commit the staged files first, and then run this tool again."
exit 1
fi
$opt_pkg || (
if [[ "$(git branch --show-current)" != "$RELEASE_BRANCH" ]]; then
echo "> Abort: Please run the tool in the '$RELEASE_BRANCH' branch."
exit 1
fi
)
}
_check_src() {
for i in "${!FILES[@]}"; do
_src="${FILES[$i]}"
if [[ ! -f $_src && ! -d $_src ]]; then
echo -e "> Error: Missing file \"$_src\"!\n"
exit 1
fi
done
}
_check_node_packages() {
if [[ ! -d node_modules || "$(du node_modules | awk '{print $1}')" == "0" ]]; then
npm i
fi
}
check() {
_check_cli
_check_git
_check_src
_check_node_packages
}
## Bump new version to gem-spec file
_bump_version() {
_version="$(grep '"version":' "$NODE_SPEC" | sed 's/.*: "//;s/".*//')"
sed -i "s/[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+/$_version/" "$GEM_SPEC"
echo "> Bump gem version to $_version"
}
_improve_changelog() {
# Replace multiple empty lines with a single empty line
sed -i '/^$/N;/^\n$/D' "$CHANGELOG"
# Escape left angle brackets of HTML tag in the changelog as they break the markdown structure. e.g., '<hr>'
sed -i -E 's/\s(<[a-z])/ \\\1/g' "$CHANGELOG"
}
prepare() {
_bump_version
_improve_changelog
}
## Build a Gem package
build_gem() {
if $opt_pkg; then
BACKUP_PATH="$(mktemp -d)"
cp "$JS_DIST"/* "$BACKUP_PATH"
fi
# Remove unnecessary theme settings
sed -i "s/^cdn:.*/cdn:/;s/^avatar:.*/avatar:/" $CONFIG
rm -f ./*.gem
npm run build
git add "$JS_DIST" -f # add JS distribution files to gem
gem build "$GEM_SPEC"
# resume the settings
git reset
git checkout .
if $opt_pkg; then
# restore the dist files for future development
mkdir -p "$JS_DIST" && cp "$BACKUP_PATH"/* "$JS_DIST"
rm -rf "$BACKUP_PATH"
fi
}
# Push the gem to RubyGems.org (using $GEM_HOST_API_KEY)
push_gem() {
gem push ./*.gem
}
## Merge the release branch into the default branch
merge() {
git fetch origin "$MAIN_BRANCH"
git checkout -b "$MAIN_BRANCH" origin/"$MAIN_BRANCH"
git merge --no-ff --no-edit "$RELEASE_BRANCH" || (
git merge --abort
echo -e "\n> Conflict detected. Aborting merge.\n"
exit 0
)
git push origin "$MAIN_BRANCH"
}
main() {
check
if $opt_pre; then
prepare
exit 0
fi
build_gem
$opt_pkg && exit 0
push_gem
merge
}
2022-02-14 18:59:17 +03:00
while (($#)); do
opt="$1"
case $opt in
--prepare)
2022-02-14 18:59:17 +03:00
opt_pre=true
shift
;;
-p | --package)
opt_pkg=true
shift
;;
2022-02-14 18:59:17 +03:00
-h | --help)
help
exit 0
;;
*)
# unknown option
help
exit 1
;;
esac
done
main