From 4237d078fa034860499d366c25fa06a014642b3e Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Sun, 10 Sep 2023 17:25:41 +0800 Subject: [PATCH] build(release): improve version release strategy --- .github/workflows/cd.yml | 5 +- tools/release | 166 +++++++++++++++++++-------------------- 2 files changed, 86 insertions(+), 85 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index af4a885..2e239a4 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -1,7 +1,10 @@ name: CD on: push: - branches: [production, docs] + tags: + - "v[0-9]+.[0-9]+.[0-9]+" + branches: + - docs jobs: launch: diff --git a/tools/release b/tools/release index 746ab96..69bfa26 100755 --- a/tools/release +++ b/tools/release @@ -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