Skip to content

Commit

Permalink
build(shell): update release tool to work with standard-version
Browse files Browse the repository at this point in the history
  • Loading branch information
cotes2020 authored and shihtiy-tw committed Nov 26, 2022
1 parent 1cc4250 commit 0881703
Show file tree
Hide file tree
Showing 2 changed files with 182 additions and 144 deletions.
106 changes: 0 additions & 106 deletions tools/bump.sh

This file was deleted.

220 changes: 182 additions & 38 deletions tools/release.sh
Original file line number Diff line number Diff line change
@@ -1,22 +1,44 @@
#!/usr/bin/env bash
#
# According to the GitLab flow release branching model,
# cherry-pick the last commit on the main branch to the release branch,
# and then create a tag and gem package on the release branch (naming format: 'release/<X.Y>').
# Release a new version to the GitLab flow production branch.
#
# For a new major/minor version, bump version on the main branch, and then merge into the production branch.
#
# Usage:
# For a patch version, bump the version number on the patch branch, then merge that branch into the main branch
# and production branch.
#
# It can be run on main branch, and it should be used after just finishing the last feature in the version plan,
# or just after merging the hotfix to the main branch.
#
# Requires: Git, Gulp
# Usage: run on main branch or the patch branch
#
# Requires: Git, Node.js, NPX and RubyGems

set -eu

opt_pre=false # preview mode option

working_branch="$(git branch --show-current)"

STAGING_BRANCH="$(git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@')"

PROD_BRANCH="production"

GEM_SPEC="jekyll-theme-chirpy.gemspec"

opt_pre=false
NODE_CONFIG="package.json"

FILES=(
"_sass/jekyll-theme-chirpy.scss"
"_javascript/copyright"
"$GEM_SPEC"
"$NODE_CONFIG"
)

TOOLS=(
"git"
"npm"
"npx"
"gem"
)

help() {
echo "A tool to release new version Chirpy gem"
Expand All @@ -26,19 +48,85 @@ help() {
echo " bash ./tools/release.sh [options]"
echo
echo "Options:"
echo " -p, --preview Enable preview mode, only pakcage, and will not modify the branches"
echo " -p, --preview Enable preview mode, only package, and will not modify the branches"
echo " -h, --help Print this information."
}

check() {
_check_git() {
# ensure nothing is uncommitted
if [[ -n $(git status . -s) ]]; then
echo "Error: Commit unstaged files first, and then run this tool againt."
exit -1
echo "Abort: Commit the staged files first, and then run this tool again."
exit 1
fi

if [[ ! -f $GEM_SPEC ]]; then
echo -e "Error: Missing file \"$GEM_SPEC\"!\n"
exit -1
# ensure the working branch is the main/patch branch
if [[ $working_branch != "$STAGING_BRANCH" && $working_branch != hotfix/* ]]; then
echo "Abort: Please run on the main branch or patch branches."
exit 1
fi
}

_check_src() {
if [[ ! -f $1 && ! -d $1 ]]; then
echo -e "Error: Missing file \"$1\"!\n"
exit 1
fi
}

_check_command() {
if ! command -v "$1" &>/dev/null; then
echo "Command '$1' not found"
exit 1
fi
}

_check_node_packages() {
if [[ ! -d node_modules || "$(du node_modules | awk '{print $1}')" == "0" ]]; then
npm i
fi
}

check() {
_check_git

for i in "${!FILES[@]}"; do
_check_src "${FILES[$i]}"
done

for i in "${!TOOLS[@]}"; do
_check_command "${TOOLS[$i]}"
done

_check_node_packages
}

_bump_file() {
for i in "${!FILES[@]}"; do
sed -i "s/v[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+/v$1/" "${FILES[$i]}"
done

npx gulp
}

_bump_gemspec() {
sed -i "s/[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+/$1/" "$GEM_SPEC"
}

# 1. Bump latest version number to the following files:
#
# - _sass/jekyll-theme-chirpy.scss
# - _javascript/copyright
# - assets/js/dist/*.js (will be built by gulp later)
# - jekyll-theme-chirpy.gemspec
#
# 2. Create a commit to save the changes.
bump() {
_bump_file "$1"
_bump_gemspec "$1"

if [[ $opt_pre = false && -n $(git status . -s) ]]; then
git add .
git commit -m "chore(release): $1"
fi
}

Expand All @@ -52,39 +140,95 @@ resume_config() {
mv _config.yml.bak _config.yml
}

release() {
_default_branch="$(git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@')"
_version="$(grep "spec.version" jekyll-theme-chirpy.gemspec | sed 's/.*= "//;s/".*//')" # X.Y.Z
_release_branch="release/${_version%.*}"

if [[ $opt_pre = "false" ]]; then
# Modify the GitLab release branches
if [[ -z $(git branch -v | grep "$_release_branch") ]]; then
# create a new release branch
git checkout -b "$_release_branch"
else
# cherry-pick the latest commit from default branch to release branch
_last_commit="$(git rev-parse "$_default_branch")"
git checkout "$_release_branch"
git cherry-pick "$_last_commit" -m 1
fi

# Create a new tag
echo -e "Create tag v$_version\n"
git tag "v$_version"
# auto-generate a new version number to the file 'package.json'
standard_version() {
if $opt_pre; then
npx standard-version --prerelease rc
else
npx standard-version
fi
}

# Prevent changelogs generated on master branch from having duplicate content
# (the another bug of `standard-version`)
standard_version_plus() {
temp_branch="prod-mirror"
temp_dir="$(mktemp -d)"

git checkout -b "$temp_branch" "$PROD_BRANCH"
git merge --no-ff --no-edit "$STAGING_BRANCH"

# build a gem package
echo -e "Build the gem pakcage for v$_version\n"
standard_version

cp package.json CHANGELOG.md "$temp_dir"

git checkout "$STAGING_BRANCH"
git reset --hard HEAD # undo the changes from $temp_branch
mv "$temp_dir"/* . # rewrite the changelog

# clean up the temp stuff
rm -rf "$temp_dir"
git branch -D "$temp_branch"
}

# build a gem package
build_gem() {
echo -e "Build the gem package for v$_version\n"
cleanup_config
rm -f ./*.gem
gem build "$GEM_SPEC"
resume_config
}

# Update the git branch graph, tag, and then build the gem package.
release() {
_version="$1" # X.Y.Z

if $opt_pre; then
$opt_pre
exit 0
fi

git checkout "$PROD_BRANCH"
git merge --no-ff --no-edit "$working_branch"

# Create a new tag on production branch
echo -e "Create tag v$_version\n"
git tag "v$_version"

build_gem

# merge from patch branch to the staging branch
# NOTE: This may break due to merge conflicts, so it may need to be resolved manually.
if [[ $working_branch == hotfix/* ]]; then
git checkout "$STAGING_BRANCH"
git merge --no-ff --no-edit "$working_branch"
git branch -D "$working_branch"
fi
}

main() {
check
release

if [[ "$working_branch" == "$STAGING_BRANCH" ]]; then
standard_version_plus
else
standard_version
fi

# Change heading of Patch version to level 2 (a bug from `standard-version`)
sed -i "s/^### \[/## \[/g" CHANGELOG.md

_version="$(grep '"version":' package.json | sed 's/.*: "//;s/".*//')"

echo -e "Bump version number to $_version\n"
bump "$_version"

release "$_version"

# Undo all changes on Git
$opt_pre && git reset --hard && git clean -fd

}

while (($#)); do
Expand Down

0 comments on commit 0881703

Please sign in to comment.