Skip to content

Commit 42fe8f5

Browse files
committed
build(shell): update release tool to work with standard-version
1 parent dd264e7 commit 42fe8f5

File tree

2 files changed

+182
-144
lines changed

2 files changed

+182
-144
lines changed

tools/bump.sh

Lines changed: 0 additions & 106 deletions
This file was deleted.

tools/release.sh

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

1515
set -eu
1616

17+
opt_pre=false # preview mode option
18+
19+
working_branch="$(git branch --show-current)"
20+
21+
STAGING_BRANCH="$(git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@')"
22+
23+
PROD_BRANCH="production"
24+
1725
GEM_SPEC="jekyll-theme-chirpy.gemspec"
1826

19-
opt_pre=false
27+
NODE_CONFIG="package.json"
28+
29+
FILES=(
30+
"_sass/jekyll-theme-chirpy.scss"
31+
"_javascript/copyright"
32+
"$GEM_SPEC"
33+
"$NODE_CONFIG"
34+
)
35+
36+
TOOLS=(
37+
"git"
38+
"npm"
39+
"npx"
40+
"gem"
41+
)
2042

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

33-
check() {
55+
_check_git() {
56+
# ensure nothing is uncommitted
3457
if [[ -n $(git status . -s) ]]; then
35-
echo "Error: Commit unstaged files first, and then run this tool againt."
36-
exit -1
58+
echo "Abort: Commit the staged files first, and then run this tool again."
59+
exit 1
3760
fi
3861

39-
if [[ ! -f $GEM_SPEC ]]; then
40-
echo -e "Error: Missing file \"$GEM_SPEC\"!\n"
41-
exit -1
62+
# ensure the working branch is the main/patch branch
63+
if [[ $working_branch != "$STAGING_BRANCH" && $working_branch != hotfix/* ]]; then
64+
echo "Abort: Please run on the main branch or patch branches."
65+
exit 1
66+
fi
67+
}
68+
69+
_check_src() {
70+
if [[ ! -f $1 && ! -d $1 ]]; then
71+
echo -e "Error: Missing file \"$1\"!\n"
72+
exit 1
73+
fi
74+
}
75+
76+
_check_command() {
77+
if ! command -v "$1" &>/dev/null; then
78+
echo "Command '$1' not found"
79+
exit 1
80+
fi
81+
}
82+
83+
_check_node_packages() {
84+
if [[ ! -d node_modules || "$(du node_modules | awk '{print $1}')" == "0" ]]; then
85+
npm i
86+
fi
87+
}
88+
89+
check() {
90+
_check_git
91+
92+
for i in "${!FILES[@]}"; do
93+
_check_src "${FILES[$i]}"
94+
done
95+
96+
for i in "${!TOOLS[@]}"; do
97+
_check_command "${TOOLS[$i]}"
98+
done
99+
100+
_check_node_packages
101+
}
102+
103+
_bump_file() {
104+
for i in "${!FILES[@]}"; do
105+
sed -i "s/v[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+/v$1/" "${FILES[$i]}"
106+
done
107+
108+
npx gulp
109+
}
110+
111+
_bump_gemspec() {
112+
sed -i "s/[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+/$1/" "$GEM_SPEC"
113+
}
114+
115+
# 1. Bump latest version number to the following files:
116+
#
117+
# - _sass/jekyll-theme-chirpy.scss
118+
# - _javascript/copyright
119+
# - assets/js/dist/*.js (will be built by gulp later)
120+
# - jekyll-theme-chirpy.gemspec
121+
#
122+
# 2. Create a commit to save the changes.
123+
bump() {
124+
_bump_file "$1"
125+
_bump_gemspec "$1"
126+
127+
if [[ $opt_pre = false && -n $(git status . -s) ]]; then
128+
git add .
129+
git commit -m "chore(release): $1"
42130
fi
43131
}
44132

@@ -52,39 +140,95 @@ resume_config() {
52140
mv _config.yml.bak _config.yml
53141
}
54142

55-
release() {
56-
_default_branch="$(git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@')"
57-
_version="$(grep "spec.version" jekyll-theme-chirpy.gemspec | sed 's/.*= "//;s/".*//')" # X.Y.Z
58-
_release_branch="release/${_version%.*}"
59-
60-
if [[ $opt_pre = "false" ]]; then
61-
# Modify the GitLab release branches
62-
if [[ -z $(git branch -v | grep "$_release_branch") ]]; then
63-
# create a new release branch
64-
git checkout -b "$_release_branch"
65-
else
66-
# cherry-pick the latest commit from default branch to release branch
67-
_last_commit="$(git rev-parse "$_default_branch")"
68-
git checkout "$_release_branch"
69-
git cherry-pick "$_last_commit" -m 1
70-
fi
71-
72-
# Create a new tag
73-
echo -e "Create tag v$_version\n"
74-
git tag "v$_version"
143+
# auto-generate a new version number to the file 'package.json'
144+
standard_version() {
145+
if $opt_pre; then
146+
npx standard-version --prerelease rc
147+
else
148+
npx standard-version
75149
fi
150+
}
151+
152+
# Prevent changelogs generated on master branch from having duplicate content
153+
# (the another bug of `standard-version`)
154+
standard_version_plus() {
155+
temp_branch="prod-mirror"
156+
temp_dir="$(mktemp -d)"
157+
158+
git checkout -b "$temp_branch" "$PROD_BRANCH"
159+
git merge --no-ff --no-edit "$STAGING_BRANCH"
76160

77-
# build a gem package
78-
echo -e "Build the gem pakcage for v$_version\n"
161+
standard_version
162+
163+
cp package.json CHANGELOG.md "$temp_dir"
164+
165+
git checkout "$STAGING_BRANCH"
166+
git reset --hard HEAD # undo the changes from $temp_branch
167+
mv "$temp_dir"/* . # rewrite the changelog
168+
169+
# clean up the temp stuff
170+
rm -rf "$temp_dir"
171+
git branch -D "$temp_branch"
172+
}
173+
174+
# build a gem package
175+
build_gem() {
176+
echo -e "Build the gem package for v$_version\n"
79177
cleanup_config
80178
rm -f ./*.gem
81179
gem build "$GEM_SPEC"
82180
resume_config
83181
}
84182

183+
# Update the git branch graph, tag, and then build the gem package.
184+
release() {
185+
_version="$1" # X.Y.Z
186+
187+
if $opt_pre; then
188+
$opt_pre
189+
exit 0
190+
fi
191+
192+
git checkout "$PROD_BRANCH"
193+
git merge --no-ff --no-edit "$working_branch"
194+
195+
# Create a new tag on production branch
196+
echo -e "Create tag v$_version\n"
197+
git tag "v$_version"
198+
199+
build_gem
200+
201+
# merge from patch branch to the staging branch
202+
# NOTE: This may break due to merge conflicts, so it may need to be resolved manually.
203+
if [[ $working_branch == hotfix/* ]]; then
204+
git checkout "$STAGING_BRANCH"
205+
git merge --no-ff --no-edit "$working_branch"
206+
git branch -D "$working_branch"
207+
fi
208+
}
209+
85210
main() {
86211
check
87-
release
212+
213+
if [[ "$working_branch" == "$STAGING_BRANCH" ]]; then
214+
standard_version_plus
215+
else
216+
standard_version
217+
fi
218+
219+
# Change heading of Patch version to level 2 (a bug from `standard-version`)
220+
sed -i "s/^### \[/## \[/g" CHANGELOG.md
221+
222+
_version="$(grep '"version":' package.json | sed 's/.*: "//;s/".*//')"
223+
224+
echo -e "Bump version number to $_version\n"
225+
bump "$_version"
226+
227+
release "$_version"
228+
229+
# Undo all changes on Git
230+
$opt_pre && git reset --hard && git clean -fd
231+
88232
}
89233

90234
while (($#)); do

0 commit comments

Comments
 (0)