diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 907b905..f2222fc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,12 +36,5 @@ jobs: ruby-version: 2.7 bundler-cache: true - - name: Build Site - env: - JEKYLL_ENV: production - run: | - bundle exec jekyll b - - name: Test Site - run: | - bash tools/test.sh + run: bash tools/deploy.sh --dry-run diff --git a/.github/workflows/pages-deploy.yml.hook b/.github/workflows/pages-deploy.yml.hook index aa90027..81a249e 100644 --- a/.github/workflows/pages-deploy.yml.hook +++ b/.github/workflows/pages-deploy.yml.hook @@ -25,29 +25,5 @@ jobs: ruby-version: 2.7 bundler-cache: true - - name: Check baseurl - run: | - baseurl="$(grep '^baseurl:' _config.yml | sed "s/.*: *//;s/['\"]//g;s/#.*//")" - if [[ -n $baseurl ]]; then - echo "BASE_URL=$baseurl" >> $GITHUB_ENV - fi - - - name: Build Site - env: - JEKYLL_ENV: production - run: | - bundle exec jekyll b -d "_site$BASE_URL" - - - name: Test Site - run: | - bash tools/test.sh - - name: Deploy - run: | - if [[ -n $BASE_URL ]]; then - mv _site$BASE_URL _site-rename - rm -rf _site - mv _site-rename _site - fi - - bash tools/deploy.sh + run: bash tools/deploy.sh diff --git a/tools/bump.sh b/tools/bump.sh index 00bed1e..8d2b6f6 100755 --- a/tools/bump.sh +++ b/tools/bump.sh @@ -1,34 +1,24 @@ #!/usr/bin/env bash # -# How does it work: # -# 1. Cherry pick the latest commit from default branch -# to the target release branch if the target release branch already existed. +# 1. Bump latest version number to the following files: # -# 2. 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 -# - package.json -# -# 3. Create a git-tag on release branch -# -# 4. Build a RubyGems package base on the latest git-tag +# - _sass/jekyll-theme-chirpy.scss +# - _javascript/copyright +# - assets/js/dist/*.js (will be built by gulp later) +# - jekyll-theme-chirpy.gemspec +# - package.json # +# 2. Then create a commit to automatically save the changes. # # Usage: # -# Run on default branch, if run on other branch requires parameter '-m' (manual mode). +# Run on the default branch or hotfix branch # -# -# Requires: Git, Gulp, RubyGems +# Requires: Git, Gulp set -eu -opt_manual=false - ASSETS=( "_sass/jekyll-theme-chirpy.scss" "_javascript/copyright" @@ -38,10 +28,6 @@ GEM_SPEC="jekyll-theme-chirpy.gemspec" NODE_META="package.json" -DEFAULT_BRANCH="master" - -_working_branch="$(git branch --show-current)" - _check_src() { if [[ ! -f $1 && ! -d $1 ]]; then echo -e "Error: Missing file \"$1\"!\n" @@ -55,12 +41,6 @@ check() { exit -1 fi - # ensure working on default branch or running in 'manual' mode - if [[ $_working_branch != $DEFAULT_BRANCH && $opt_manual == "false" ]]; then - echo "Error: This operation must be performed on the 'master' branch or '--manual' mode!" - exit -1 - fi - for i in "${!ASSETS[@]}"; do _check_src "${ASSETS[$i]}" done @@ -98,75 +78,6 @@ bump() { fi } -build_gem() { - rm -f ./*.gem - gem build "$GEM_SPEC" -} - -release() { - _version="$1" - _major="" - _minor="" - _new_release_branch=false - - IFS='.' read -r -a array <<< "$_version" - - for elem in "${array[@]}"; do - if [[ -z $_major ]]; then - _major="$elem" - elif [[ -z $_minor ]]; then - _minor="$elem" - else - break - fi - done - - _release_branch="$_major-$_minor-stable" - - if ! $opt_manual; then - if [[ -z $(git branch -v | grep "$_release_branch") ]]; then - git checkout -b "$_release_branch" - _new_release_branch=true - 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 - - fi - - echo -e "Bump version to $_version\n" - bump "$_version" - - echo -e "Create tag v$_version\n" - git tag "v$_version" - - echo -e "Build the gem pakcage for v$_version\n" - build_gem - - # head back to working branch - git checkout "$_working_branch" - - if [[ $_working_branch == $DEFAULT_BRANCH ]]; then - if $_new_release_branch; then - git merge "$_release_branch" - fi - fi - -} - -help() { - echo "Bump new version to Chirpy project" - echo "Usage:" - echo - echo " bash /path/to/bump.sh [options]" - echo - echo "Options:" - echo " -m, --manual Manual relase, bump version only." - echo " -h, --help Print this help information." -} - main() { check @@ -183,7 +94,8 @@ main() { exit -1 fi - release "$_version" + echo -e "Bump version to $_version\n" + bump "$_version" else @@ -192,22 +104,4 @@ main() { } -while (($#)); do - opt="$1" - case $opt in - -m | --manual) - opt_manual=true - shift - ;; - -h | --help) - help - exit 0 - ;; - *) - echo "unknown option '$opt'!" - exit 1 - ;; - esac -done - main diff --git a/tools/deploy.sh b/tools/deploy.sh index 7e17108..84b2b10 100755 --- a/tools/deploy.sh +++ b/tools/deploy.sh @@ -1,22 +1,80 @@ #!/usr/bin/env bash # -# Deploy the content of _site to 'origin/' +# Build, test and then deploy the site content to 'origin/' +# +# Requirement: html-proofer, jekyll +# +# Usage: See help information set -eu PAGES_BRANCH="gh-pages" -_no_branch=false +SITE_DIR="_site" + +_opt_dry_run=false + +_config="_config.yml" + +_no_pages_branch=false + _backup_dir="$(mktemp -d)" +_baseurl="" + +help() { + echo "Build, test and then deploy the site content to 'origin/'" + echo + echo "Usage:" + echo + echo " bash ./tools/deploy.sh [options]" + echo + echo "Options:" + echo ' -c, --config "" Specify config file(s)' + echo " --dry-run Build site and test, but not deploy" + echo " -h, --help Print this information." +} + init() { - if [[ -z ${GITHUB_ACTION+x} ]]; then - echo "ERROR: This script is not allowed to run outside of GitHub Action." + if [[ -z ${GITHUB_ACTION+x} && $_opt_dry_run == 'false' ]]; then + echo "ERROR: It is not allowed to deploy outside of the GitHub Action envrionment." + echo "Type option '-h' to see the help information." exit -1 fi + _baseurl="$(grep '^baseurl:' _config.yml | sed "s/.*: *//;s/['\"]//g;s/#.*//")" +} + +build() { + # clean up + if [[ -d $SITE_DIR ]]; then + rm -rf "$SITE_DIR" + fi + + # build + JEKYLL_ENV=production bundle exec jekyll b -d "$SITE_DIR$_baseurl" --config "$_config" +} + +test() { + bundle exec htmlproofer \ + --disable-external \ + --check-html \ + --allow_hash_href \ + "$SITE_DIR" +} + +resume_site_dir() { + if [[ -n $_baseurl ]]; then + # Move the site file to the regular directory '_site' + mv "$SITE_DIR$_baseurl" "${SITE_DIR}-rename" + rm -rf "$SITE_DIR" + mv "${SITE_DIR}-rename" "$SITE_DIR" + fi +} + +setup_gh() { if [[ -z $(git branch -av | grep "$PAGES_BRANCH") ]]; then - _no_branch=true + _no_pages_branch=true git checkout -b "$PAGES_BRANCH" else git checkout "$PAGES_BRANCH" @@ -24,7 +82,7 @@ init() { } backup() { - mv _site/* "$_backup_dir" + mv "$SITE_DIR"/* "$_backup_dir" mv .git "$_backup_dir" # When adding custom domain from Github website, @@ -50,7 +108,7 @@ deploy() { git add -A git commit -m "[Automation] Site update No.${GITHUB_RUN_NUMBER}" - if $_no_branch; then + if $_no_pages_branch; then git push -u origin "$PAGES_BRANCH" else git push -f @@ -59,9 +117,43 @@ deploy() { main() { init + build + test + resume_site_dir + + if $_opt_dry_run; then + exit 0 + fi + + setup_gh backup flush deploy } +while (($#)); do + opt="$1" + case $opt in + -c | --config) + _config="$2" + shift + shift + ;; + --dry-run) + # build & test, but not deploy + _opt_dry_run=true + shift + ;; + -h | --help) + help + exit 0 + ;; + *) + # unknown option + help + exit 1 + ;; + esac +done + main diff --git a/tools/init.sh b/tools/init.sh index 2ab78df..5035ff2 100755 --- a/tools/init.sh +++ b/tools/init.sh @@ -16,6 +16,13 @@ help() { echo " -h, --help Print this help information." } +check_status() { + if [[ -n $(git status . -s) ]]; then + echo "Error: Commit unstaged files first, and then run this tool againt." + exit -1 + fi +} + check_init() { local _has_inited=false @@ -40,25 +47,40 @@ check_init() { } init_files() { - if $_no_gh; then rm -rf .github else + # change the files of `.github` mv .github/workflows/$ACTIONS_WORKFLOW.hook . rm -rf .github mkdir -p .github/workflows mv ./${ACTIONS_WORKFLOW}.hook .github/workflows/${ACTIONS_WORKFLOW} + + # ensure the gh-actions trigger branch + + _workflow=".github/workflows/${ACTIONS_WORKFLOW}" + _default_branch="$(git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@')" + _lineno="$(sed -n "/branches:/=" "$_workflow")" + sed -i "$((_lineno + 1))s/- .*/- ${_default_branch}/" "$_workflow" + fi + # trace the gem lockfile on user-end + sed -i "/Gemfile.lock/d" .gitignore + + # remove the other fies rm -f .travis.yml rm -rf _posts/* docs + # save changes git add -A && git add .github -f git commit -m "[Automation] Initialize the environment." -q echo "[INFO] Initialization successful!" } +check_status + check_init _no_gh=false diff --git a/tools/release.sh b/tools/release.sh new file mode 100755 index 0000000..ef5892b --- /dev/null +++ b/tools/release.sh @@ -0,0 +1,62 @@ +#!/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/'). +# +# +# Usage: +# +# 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 + +set -eu + +GEM_SPEC="jekyll-theme-chirpy.gemspec" + +check() { + if [[ -n $(git status . -s) ]]; then + echo "Error: Commit unstaged files first, and then run this tool againt." + exit -1 + fi + + if [[ ! -f $GEM_SPEC ]]; then + echo -e "Error: Missing file \"$GEM_SPEC\"!\n" + exit -1 + fi +} + +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 [[ -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 new tag + echo -e "Create tag v$_version\n" + git tag "v$_version" + + # build a gem package + echo -e "Build the gem pakcage for v$_version\n" + rm -f ./*.gem + gem build "$GEM_SPEC" + +} + +main() { + check + release +} + +main diff --git a/tools/test.sh b/tools/test.sh deleted file mode 100755 index ecaf8c8..0000000 --- a/tools/test.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env bash -# -# Using HTML-proofer to test site. -# -# Requirement: https://github.com/gjtorikian/html-proofer -# -# Usage: bash /path/to/test.sh [indicated path] - -DEST=_site - -_build=false - -help() { - echo "Usage:" - echo - echo " bash ./tools/test.sh [options]" - echo - echo "Options:" - echo " --build Run Jekyll build before test." - echo " -d, --dir Specify the test path." - echo " -h, --help Print this information." -} - -if [[ -n $1 && -d $1 ]]; then - DEST=$1 -fi - -while (($#)); do - opt="$1" - case $opt in - --build) - _build=true - shift - ;; - -d | --dir) - if [[ ! -d $2 ]]; then - echo -e "Error: path '$2' doesn't exist\n" - help - exit 1 - fi - DEST=$2 - shift - shift - ;; - -h | --help) - help - exit 0 - ;; - *) - # unknown option - help - exit 1 - ;; - esac -done - -if $_build; then - JEKYLL_ENV=production bundle exec jekyll b -fi - -bundle exec htmlproofer "$DEST" \ - --disable-external \ - --check-html \ - --allow_hash_href