cut.sh 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. #!/usr/bin/env bash
  2. ## cut a new 5.x release for EMQX (opensource or enterprise).
  3. set -euo pipefail
  4. if [ "${DEBUG:-}" = 1 ]; then
  5. set -x
  6. fi
  7. # ensure dir
  8. cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")/../.."
  9. usage() {
  10. cat <<EOF
  11. $0 RELEASE_GIT_TAG [option]
  12. RELEASE_GIT_TAG is a 'v*' or 'e*' tag for example:
  13. v5.0.12
  14. e5.0.0-beta.6
  15. options:
  16. -h|--help: Print this usage.
  17. -b|--base: Specify the current release base branch, can be one of
  18. release-50
  19. NOTE: this option should be used when --dryrun.
  20. --dryrun: Do not actually create the git tag.
  21. --skip-appup: Skip checking appup
  22. Useful when you are sure that appup is already updated'
  23. NOTE: For 5.0 series the current working branch must be 'release-50' for opensource edition
  24. and 'release-e50' for enterprise edition.
  25. --.--[ master ]---------------------------.-----------.---
  26. \\ /
  27. \`---[release-50]----(v5.0.12 | e5.0.0)
  28. EOF
  29. }
  30. logerr() {
  31. echo "$(tput setaf 1)ERROR: $1$(tput sgr0)"
  32. }
  33. logmsg() {
  34. echo "INFO: $1"
  35. }
  36. TAG="${1:-}"
  37. case "$TAG" in
  38. v*)
  39. TAG_PREFIX='v'
  40. PROFILE='emqx'
  41. SKIP_APPUP='yes'
  42. ;;
  43. e*)
  44. TAG_PREFIX='e'
  45. PROFILE='emqx-enterprise'
  46. #TODO change to no when we are ready to support hot-upgrade
  47. SKIP_APPUP='yes'
  48. ;;
  49. -h|--help)
  50. usage
  51. exit 0
  52. ;;
  53. *)
  54. logerr "Unknown version tag $TAG"
  55. usage
  56. exit 1
  57. ;;
  58. esac
  59. shift 1
  60. DRYRUN='no'
  61. while [ "$#" -gt 0 ]; do
  62. case $1 in
  63. -h|--help)
  64. usage
  65. exit 0
  66. ;;
  67. --skip-appup)
  68. shift
  69. SKIP_APPUP='yes'
  70. ;;
  71. --dryrun)
  72. shift
  73. DRYRUN='yes'
  74. ;;
  75. -b|--base)
  76. BASE_BR="${2:-}"
  77. if [ -z "${BASE_BR}" ]; then
  78. logerr "Must specify which base branch"
  79. exit 1
  80. fi
  81. shift 2
  82. ;;
  83. *)
  84. logerr "Unknown option $1"
  85. exit 1
  86. ;;
  87. esac
  88. done
  89. rel_branch() {
  90. local tag="$1"
  91. case "$tag" in
  92. v5.0.*)
  93. echo 'release-50'
  94. ;;
  95. e5.0.*)
  96. echo 'release-50'
  97. ;;
  98. *)
  99. logerr "Unsupported version tag $TAG"
  100. exit 1
  101. ;;
  102. esac
  103. }
  104. ## Ensure the current work branch
  105. assert_work_branch() {
  106. local tag="$1"
  107. local release_branch
  108. release_branch="$(rel_branch "$tag")"
  109. local base_branch
  110. base_branch="${BASE_BR:-$(git branch --show-current)}"
  111. if [ "$base_branch" != "$release_branch" ]; then
  112. logerr "Base branch: $base_branch"
  113. logerr "Relase tag must be on the release branch: $release_branch"
  114. logerr "or must use -b|--base option to specify which release branch is current branch based on"
  115. exit 1
  116. fi
  117. }
  118. assert_work_branch "$TAG"
  119. ## Ensure no dirty changes
  120. assert_not_dirty() {
  121. local diff
  122. diff="$(git diff --name-only)"
  123. if [ -n "$diff" ]; then
  124. logerr "Git status is not clean? Changed files:"
  125. logerr "$diff"
  126. exit 1
  127. fi
  128. }
  129. assert_not_dirty
  130. ## Assert that the tag is not already created
  131. assert_tag_absent() {
  132. local tag="$1"
  133. ## Fail if the tag already exists
  134. EXISTING="$(git tag --list "$tag")"
  135. if [ -n "$EXISTING" ]; then
  136. logerr "$tag already released?"
  137. logerr 'This script refuse to force re-tag.'
  138. logerr 'If re-tag is intended, you must first delete the tag from both local and remote'
  139. exit 1
  140. fi
  141. }
  142. assert_tag_absent "$TAG"
  143. PKG_VSN=$(./pkg-vsn.sh "$PROFILE")
  144. ## Assert package version is updated to the tag which is being created
  145. assert_release_version() {
  146. local tag="$1"
  147. # shellcheck disable=SC2001
  148. pkg_vsn="$(echo "$PKG_VSN" | sed 's/-g[0-9a-f]\{8\}$//g')"
  149. if [ "${TAG_PREFIX}${pkg_vsn}" != "${tag}" ]; then
  150. logerr "The release version ($pkg_vsn) is different from the desired git tag."
  151. logerr "Update the release version in emqx_release.hrl"
  152. exit 1
  153. fi
  154. }
  155. assert_release_version "$TAG"
  156. ## Check if all upstream branches are merged
  157. if [ -z "${BASE_BR:-}" ]; then
  158. ./scripts/rel/sync-remotes.sh
  159. else
  160. ./scripts/rel/sync-remotes.sh --base "$BASE_BR"
  161. fi
  162. ## Check if the Chart versions are in sync
  163. ./scripts/rel/check-chart-vsn.sh "$PROFILE"
  164. ## Check if app versions are bumped
  165. ./scripts/apps-version-check.sh
  166. ## Ensure appup files are updated
  167. if [ "$SKIP_APPUP" = 'no' ]; then
  168. logmsg "Checking appups"
  169. ./scripts/update-appup.sh "$PROFILE" --check
  170. else
  171. logmsg "Skipped checking appup updates"
  172. fi
  173. ## Ensure relup paths are updated
  174. ## TODO: add relup path db
  175. #./scripts/relup-base-vsns.escript check-vsn-db "$PKG_VSN" "$RELUP_PATHS"
  176. ## Run some additional checks (e.g. some for enterprise edition only)
  177. CHECKS_DIR="./scripts/rel/checks"
  178. if [ -d "${CHECKS_DIR}" ]; then
  179. CHECKS="$(find "${CHECKS_DIR}" -name "*.sh" -print0 2>/dev/null | xargs -0)"
  180. for c in $CHECKS; do
  181. logmsg "Executing $c"
  182. $c
  183. done
  184. fi
  185. generate_changelog () {
  186. local CHANGES_EN_MD="changes/${TAG}-en.md" CHANGES_ZH_MD="changes/${TAG}-zh.md"
  187. ./scripts/format-changelog.sh "${TAG}" "en" > "$CHANGES_EN_MD"
  188. ./scripts/format-changelog.sh "${TAG}" "zh" > "$CHANGES_ZH_MD"
  189. git add "$CHANGES_EN_MD" "$CHANGES_ZH_MD"
  190. [ -n "$(git status -s)" ] && git commit -m "chore: Generate changelog for ${TAG}"
  191. }
  192. if [ "$DRYRUN" = 'yes' ]; then
  193. logmsg "Release tag is ready to be created with command: git tag $TAG"
  194. else
  195. case "$TAG" in
  196. *rc*)
  197. true
  198. ;;
  199. *alpha*)
  200. true
  201. ;;
  202. *beta*)
  203. true
  204. ;;
  205. e5.0.0*)
  206. # the first release has no change log
  207. true
  208. ;;
  209. *)
  210. generate_changelog
  211. ;;
  212. esac
  213. git tag "$TAG"
  214. logmsg "$TAG is created OK."
  215. fi