build(release): improve version release strategy

This commit is contained in:
Cotes Chung 2023-09-10 17:25:41 +08:00
parent 806fa3aa1a
commit 4237d078fa
No known key found for this signature in database
GPG key ID: 0D9E54843167A808
2 changed files with 86 additions and 85 deletions

View file

@ -1,7 +1,10 @@
name: CD
on:
push:
branches: [production, docs]
tags:
- "v[0-9]+.[0-9]+.[0-9]+"
branches:
- docs
jobs:
launch:

View file

@ -14,17 +14,16 @@
set -eu
opt_pre=false # preview mode option
opt_skip_ver=false # option for skip versioning
opt_pre=false # preview mode option
working_branch="$(git branch --show-current)"
# AKA the default branch, main/master branch
STAGING_BRANCH="$(git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@')"
PROD_BRANCH="production"
GEM_SPEC="jekyll-theme-chirpy.gemspec"
NODE_CONFIG="package.json"
JS_DIST="assets/js/dist"
@ -50,21 +49,30 @@ help() {
echo " bash ./tools/release [options]"
echo
echo "Options:"
echo " -k, --skip-versioning Skip the step of generating the version number."
echo " -p, --preview Enable preview mode, only package, and will not modify the branches"
echo " -h, --help Print this information."
}
_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 nothing is uncommitted
if [[ -n $(git status . -s) ]]; then
echo "Abort: Commit the staged files first, and then run this tool again."
echo "> Abort: Commit the staged files first, and then run this tool again."
exit 1
fi
# ensure the working branch is the main/patch branch
# ensure the working branch is the default/patch branch
if [[ $working_branch != "$STAGING_BRANCH" && $working_branch != hotfix/* ]]; then
echo "Abort: Please run on the main branch or patch branches."
echo "> Abort: Please run on the $STAGING_BRANCH branch or a patch branche."
exit 1
fi
}
@ -73,18 +81,7 @@ _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_command() {
for i in "${!TOOLS[@]}"; do
cli="${TOOLS[$i]}"
if ! command -v "$cli" &>/dev/null; then
echo "Command '$cli' not found!"
echo -e "> Error: Missing file \"$_src\"!\n"
exit 1
fi
done
@ -97,26 +94,55 @@ _check_node_packages() {
}
check() {
_check_command
_check_cli
_check_git
_check_src
_check_node_packages
}
## Bump latest version number and create a commit to save the changes
bump() {
sed -i "s/[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+/$1/" "$GEM_SPEC"
if [[ $opt_pre = false && -n $(git status . -s) ]]; then
git add .
git commit -m "chore(release): $1"
# auto-generate a new version number to the file 'package.json' and
bump_node() {
if $opt_pre; then
standard-version --prerelease rc
else
standard-version
fi
# Change heading of Patch version to heading level 2 (a bug from `standard-version`)
sed -i "s/^### \[/## \[/g" CHANGELOG.md
# Replace multiple empty lines with a single empty line
sed -i "/^$/N;/^\n$/D" CHANGELOG.md
}
## Bump new version to gem config file
bump_gem() {
sed -i "s/[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+/$1/" "$GEM_SPEC"
}
# Update the git branches, create a new tag, and then build the gem package.
release() {
_version="$1" # X.Y.Z
_latest_commit="$(git rev-parse HEAD)"
# Create a new tag on production branch
echo -e "> Create tag v$_version\n"
git tag "v$_version"
git checkout "$STAGING_BRANCH"
if [[ $working_branch == hotfix/* ]]; then
git merge --no-ff --no-edit "$working_branch"
# delete the patch branch
git branch -D "$working_branch"
fi
# cherry-pick the latest commit from production branch to default branch
git cherry-pick "$_latest_commit"
}
## Build a gem package
build_gem() {
echo -e "Build the gem package for v$_version\n"
# Remove unnecessary theme settings
sed -i "s/^img_cdn:.*/img_cdn:/;s/^avatar:.*/avatar:/" _config.yml
rm -f ./*.gem
@ -129,62 +155,38 @@ build_gem() {
# Resume the settings
git reset
git checkout .
}
# Update the git branch graph, tag, and then build the gem package.
release() {
_version="$1" # X.Y.Z
git checkout "$PROD_BRANCH"
git merge --no-ff --no-edit "$working_branch"
# Create a new tag on working branch
echo -e "Create tag v$_version\n"
git tag "v$_version"
# Merge from patch branch to the staging branch
if [[ $working_branch == hotfix/* ]]; then
git checkout "$STAGING_BRANCH"
git merge --no-ff --no-edit "$working_branch"
git branch -D "$working_branch"
fi
}
main() {
if [[ $opt_skip_ver = false ]]; then
check
# auto-generate a new version number to the file 'package.json'
if $opt_pre; then
standard-version --prerelease rc
else
standard-version
fi
fi
# Change heading of Patch version to level 2 (a bug from `standard-version`)
sed -i "s/^### \[/## \[/g" CHANGELOG.md
# Replace multiple empty lines with a single empty line
sed -i "/^$/N;/^\n$/D" CHANGELOG.md
_version="$(grep '"version":' "$NODE_CONFIG" | sed 's/.*: "//;s/".*//')"
echo -e "Bump version number to $_version\n"
bump "$_version"
build_gem
if [[ $opt_pre = true ]]; then
# Undo all changes on Git
git reset --hard && git clean -fd
else
release "$_version"
fi
# restore the dist files for future development
mkdir -p "$JS_DIST" && cp "$BACKUP_PATH"/* "$JS_DIST"
}
main() {
check
if [[ $opt_pre = false ]]; then
git checkout "$PROD_BRANCH"
git merge --no-ff --no-edit "$working_branch"
fi
bump_node
_version="$(grep '"version":' "$NODE_CONFIG" | sed 's/.*: "//;s/".*//')"
bump_gem "$_version"
echo -e "> Build the gem package for v$_version\n"
if [[ $opt_pre = false ]]; then
echo -e "> Bumped version number to $_version\n"
git add .
git commit -m "chore(release): $_version"
release "$_version"
fi
build_gem
}
while (($#)); do
opt="$1"
case $opt in
@ -192,10 +194,6 @@ while (($#)); do
opt_pre=true
shift
;;
-k | --skip-versioning)
opt_skip_ver=true
shift
;;
-h | --help)
help
exit 0